LCOV - code coverage report
Current view: top level - sc/source/ui/unoobj - cellvaluebinding.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 121 250 48.4 %
Date: 2014-04-11 Functions: 20 30 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "cellvaluebinding.hxx"
      21             : #include <tools/debug.hxx>
      22             : #include <rtl/math.hxx>
      23             : #include <com/sun/star/table/XCellRange.hpp>
      24             : #include <com/sun/star/sheet/XCellAddressable.hpp>
      25             : #include <com/sun/star/sheet/XCellRangeData.hpp>
      26             : #include <com/sun/star/container/XIndexAccess.hpp>
      27             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      28             : #include <com/sun/star/beans/NamedValue.hpp>
      29             : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
      30             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
      31             : #include <com/sun/star/util/NumberFormat.hpp>
      32             : #include <cppuhelper/supportsservice.hxx>
      33             : 
      34             : 
      35             : namespace calc
      36             : {
      37             : 
      38             : 
      39             : #define PROP_HANDLE_BOUND_CELL  1
      40             : 
      41             :     using namespace ::com::sun::star::uno;
      42             :     using namespace ::com::sun::star::lang;
      43             :     using namespace ::com::sun::star::table;
      44             :     using namespace ::com::sun::star::text;
      45             :     using namespace ::com::sun::star::sheet;
      46             :     using namespace ::com::sun::star::container;
      47             :     using namespace ::com::sun::star::beans;
      48             :     using namespace ::com::sun::star::util;
      49             :     using namespace ::com::sun::star::form::binding;
      50             : 
      51             : #ifdef DBG_UTIL
      52             :     const char* OCellValueBinding::checkConsistency_static( const void* _pThis )
      53             :     {
      54             :         return static_cast< const OCellValueBinding* >( _pThis )->checkConsistency( );
      55             :     }
      56             : 
      57             :     const char* OCellValueBinding::checkConsistency( ) const
      58             :     {
      59             :         const char* pAssertion = NULL;
      60             :         if ( m_xCellText.is() && !m_xCell.is() )
      61             :             // there are places (e.g. getSupportedTypes) which rely on the fact
      62             :             // that m_xCellText.is() implies m_xCell.is()
      63             :             pAssertion = "cell references inconsistent!";
      64             : 
      65             :         // TODO: place any additional checks here to ensure consistency of this instance
      66             :         return pAssertion;
      67             :     }
      68             : #endif
      69             : 
      70             : 
      71           3 :     OCellValueBinding::OCellValueBinding( const Reference< XSpreadsheetDocument >& _rxDocument, bool _bListPos )
      72             :         :OCellValueBinding_Base( m_aMutex )
      73             :         ,OCellValueBinding_PBase( OCellValueBinding_Base::rBHelper )
      74             :         ,m_xDocument( _rxDocument )
      75             :         ,m_aModifyListeners( m_aMutex )
      76             :         ,m_bInitialized( false )
      77           3 :         ,m_bListPos( _bListPos )
      78             :     {
      79             :         // register our property at the base class
      80           3 :         CellAddress aInitialPropValue;
      81             :         registerPropertyNoMember(
      82             :             OUString( "BoundCell" ),
      83             :             PROP_HANDLE_BOUND_CELL,
      84             :             PropertyAttribute::BOUND | PropertyAttribute::READONLY,
      85           3 :             ::getCppuType( &aInitialPropValue ),
      86             :             &aInitialPropValue
      87           3 :         );
      88             : 
      89             :         // TODO: implement a ReadOnly property as required by the service,
      90             :         // which probably maps to the cell being locked
      91           3 :     }
      92             : 
      93             : 
      94           9 :     OCellValueBinding::~OCellValueBinding( )
      95             :     {
      96           3 :         if ( !OCellValueBinding_Base::rBHelper.bDisposed )
      97             :         {
      98           0 :             acquire();  // prevent duplicate dtor
      99           0 :             dispose();
     100             :         }
     101           6 :     }
     102             : 
     103             : 
     104          81 :     IMPLEMENT_FORWARD_XINTERFACE2( OCellValueBinding, OCellValueBinding_Base, OCellValueBinding_PBase )
     105             : 
     106             : 
     107           0 :     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCellValueBinding, OCellValueBinding_Base, OCellValueBinding_PBase )
     108             : 
     109             : 
     110           3 :     void SAL_CALL OCellValueBinding::disposing()
     111             :     {
     112           3 :         Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
     113           3 :         if ( xBroadcaster.is() )
     114             :         {
     115           0 :             xBroadcaster->removeModifyListener( this );
     116             :         }
     117             : 
     118           3 :         WeakAggComponentImplHelperBase::disposing();
     119             : 
     120             :         // TODO: clean up here whatever you need to clean up (e.g. deregister as XEventListener
     121             :         // for the cell)
     122           3 :     }
     123             : 
     124             : 
     125           1 :     Reference< XPropertySetInfo > SAL_CALL OCellValueBinding::getPropertySetInfo(  ) throw(RuntimeException, std::exception)
     126             :     {
     127           1 :         return createPropertySetInfo( getInfoHelper() ) ;
     128             :     }
     129             : 
     130             : 
     131           1 :     ::cppu::IPropertyArrayHelper& SAL_CALL OCellValueBinding::getInfoHelper()
     132             :     {
     133           1 :         return *OCellValueBinding_PABase::getArrayHelper();
     134             :     }
     135             : 
     136             : 
     137           1 :     ::cppu::IPropertyArrayHelper* OCellValueBinding::createArrayHelper( ) const
     138             :     {
     139           1 :         Sequence< Property > aProps;
     140           1 :         describeProperties( aProps );
     141           1 :         return new ::cppu::OPropertyArrayHelper(aProps);
     142             :     }
     143             : 
     144             : 
     145           0 :     void SAL_CALL OCellValueBinding::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
     146             :     {
     147             :         OSL_ENSURE( _nHandle == PROP_HANDLE_BOUND_CELL, "OCellValueBinding::getFastPropertyValue: invalid handle!" );
     148             :             // we only have this one property ....
     149             :         (void)_nHandle;     // avoid warning in product version
     150             : 
     151           0 :         _rValue.clear();
     152           0 :         Reference< XCellAddressable > xCellAddress( m_xCell, UNO_QUERY );
     153           0 :         if ( xCellAddress.is() )
     154           0 :             _rValue <<= xCellAddress->getCellAddress( );
     155           0 :     }
     156             : 
     157             : 
     158           3 :     Sequence< Type > SAL_CALL OCellValueBinding::getSupportedValueTypes(  ) throw (RuntimeException, std::exception)
     159             :     {
     160           3 :         checkDisposed( );
     161           3 :         checkInitialized( );
     162             : 
     163           3 :         sal_Int32 nCount = m_xCellText.is() ? 3 : m_xCell.is() ? 1 : 0;
     164           3 :         if ( m_bListPos )
     165           3 :             ++nCount;
     166             : 
     167           3 :         Sequence< Type > aTypes( nCount );
     168           3 :         if ( m_xCell.is() )
     169             :         {
     170             :             // an XCell can be used to set/get "double" values
     171           3 :             aTypes[0] = ::getCppuType( static_cast< double* >( NULL ) );
     172           3 :             if ( m_xCellText.is() )
     173             :             {
     174             :                 // an XTextRange can be used to set/get "string" values
     175           3 :                 aTypes[1] = ::getCppuType( static_cast< OUString* >( NULL ) );
     176             :                 // and additionally, we use it to handle booleans
     177           3 :                 aTypes[2] = ::getCppuType( static_cast< sal_Bool* >( NULL ) );
     178             :             }
     179             : 
     180             :             // add sal_Int32 only if constructed as ListPositionCellBinding
     181           3 :             if ( m_bListPos )
     182           3 :                 aTypes[nCount-1] = ::getCppuType( static_cast< sal_Int32* >( NULL ) );
     183             :         }
     184             : 
     185           3 :         return aTypes;
     186             :     }
     187             : 
     188             : 
     189           3 :     sal_Bool SAL_CALL OCellValueBinding::supportsType( const Type& aType ) throw (RuntimeException, std::exception)
     190             :     {
     191           3 :         checkDisposed( );
     192           3 :         checkInitialized( );
     193             : 
     194             :         // look up in our sequence
     195           3 :         Sequence< Type > aSupportedTypes( getSupportedValueTypes() );
     196           3 :         const Type* pTypes = aSupportedTypes.getConstArray();
     197           3 :         const Type* pTypesEnd = aSupportedTypes.getConstArray() + aSupportedTypes.getLength();
     198          12 :         while ( pTypes != pTypesEnd )
     199           9 :             if ( aType.equals( *pTypes++ ) )
     200           3 :                 return sal_True;
     201             : 
     202           0 :         return false;
     203             :     }
     204             : 
     205             : 
     206           1 :     Any SAL_CALL OCellValueBinding::getValue( const Type& aType ) throw (IncompatibleTypesException, RuntimeException, std::exception)
     207             :     {
     208           1 :         checkDisposed( );
     209           1 :         checkInitialized( );
     210           1 :         checkValueType( aType );
     211             : 
     212           1 :         Any aReturn;
     213           1 :         switch ( aType.getTypeClass() )
     214             :         {
     215             :         case TypeClass_STRING:
     216             :             OSL_ENSURE( m_xCellText.is(), "OCellValueBinding::getValue: don't have a text!" );
     217           0 :             if ( m_xCellText.is() )
     218           0 :                 aReturn <<= m_xCellText->getString();
     219             :             else
     220           0 :                 aReturn <<= OUString();
     221           0 :             break;
     222             : 
     223             :         case TypeClass_BOOLEAN:
     224             :             OSL_ENSURE( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
     225           1 :             if ( m_xCell.is() )
     226             :             {
     227             :                 // check if the cell has a numeric value (this might go into a helper function):
     228             : 
     229           1 :                 sal_Bool bHasValue = false;
     230           1 :                 CellContentType eCellType = m_xCell->getType();
     231           1 :                 if ( eCellType == CellContentType_VALUE )
     232           1 :                     bHasValue = sal_True;
     233           0 :                 else if ( eCellType == CellContentType_FORMULA )
     234             :                 {
     235             :                     // check if the formula result is a value
     236           0 :                     if ( m_xCell->getError() == 0 )
     237             :                     {
     238           0 :                         Reference<XPropertySet> xProp( m_xCell, UNO_QUERY );
     239           0 :                         if ( xProp.is() )
     240             :                         {
     241             :                             CellContentType eResultType;
     242           0 :                             if ( (xProp->getPropertyValue("FormulaResultType") >>= eResultType) && eResultType == CellContentType_VALUE )
     243           0 :                                 bHasValue = sal_True;
     244           0 :                         }
     245             :                     }
     246             :                 }
     247             : 
     248           1 :                 if ( bHasValue )
     249             :                 {
     250             :                     // 0 is "unchecked", any other value is "checked", regardless of number format
     251           1 :                     double nCellValue = m_xCell->getValue();
     252           1 :                     sal_Bool bBoolValue = ( nCellValue != 0.0 );
     253           1 :                     aReturn <<= bBoolValue;
     254             :                 }
     255             :                 // empty cells, text cells and text or error formula results: leave return value empty
     256             :             }
     257           1 :             break;
     258             : 
     259             :         case TypeClass_DOUBLE:
     260             :             OSL_ENSURE( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
     261           0 :             if ( m_xCell.is() )
     262           0 :                 aReturn <<= m_xCell->getValue();
     263             :             else
     264           0 :                 aReturn <<= (double)0;
     265           0 :             break;
     266             : 
     267             :         case TypeClass_LONG:
     268             :             OSL_ENSURE( m_xCell.is(), "OCellValueBinding::getValue: don't have a double value supplier!" );
     269           0 :             if ( m_xCell.is() )
     270             :             {
     271             :                 // The list position value in the cell is 1-based.
     272             :                 // We subtract 1 from any cell value (no special handling for 0 or negative values).
     273             : 
     274           0 :                 sal_Int32 nValue = (sal_Int32) rtl::math::approxFloor( m_xCell->getValue() );
     275           0 :                 --nValue;
     276             : 
     277           0 :                 aReturn <<= nValue;
     278             :             }
     279             :             else
     280           0 :                 aReturn <<= (sal_Int32)0;
     281           0 :             break;
     282             : 
     283             :         default:
     284             :             OSL_FAIL( "OCellValueBinding::getValue: unreachable code!" );
     285             :                 // a type other than double and string should never have survived the checkValueType
     286             :                 // above
     287             :         }
     288           1 :         return aReturn;
     289             :     }
     290             : 
     291             : 
     292           0 :     void SAL_CALL OCellValueBinding::setValue( const Any& aValue ) throw (IncompatibleTypesException, NoSupportException, RuntimeException, std::exception)
     293             :     {
     294           0 :         checkDisposed( );
     295           0 :         checkInitialized( );
     296           0 :         if ( aValue.hasValue() )
     297           0 :             checkValueType( aValue.getValueType() );
     298             : 
     299           0 :         switch ( aValue.getValueType().getTypeClass() )
     300             :         {
     301             :         case TypeClass_STRING:
     302             :             {
     303             :                 OSL_ENSURE( m_xCellText.is(), "OCellValueBinding::setValue: don't have a text!" );
     304             : 
     305           0 :                 OUString sText;
     306           0 :                 aValue >>= sText;
     307           0 :                 if ( m_xCellText.is() )
     308           0 :                     m_xCellText->setString( sText );
     309             :             }
     310           0 :             break;
     311             : 
     312             :         case TypeClass_BOOLEAN:
     313             :             {
     314             :                 OSL_ENSURE( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
     315             : 
     316             :                 // boolean is stored as values 0 or 1
     317             :                 // TODO: set the number format to boolean if no format is set?
     318             : 
     319           0 :                 sal_Bool bValue( false );
     320           0 :                 aValue >>= bValue;
     321           0 :                 double nCellValue = bValue ? 1.0 : 0.0;
     322             : 
     323           0 :                 if ( m_xCell.is() )
     324           0 :                     m_xCell->setValue( nCellValue );
     325             : 
     326           0 :                 setBooleanFormat();
     327             :             }
     328           0 :             break;
     329             : 
     330             :         case TypeClass_DOUBLE:
     331             :             {
     332             :                 OSL_ENSURE( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
     333             : 
     334           0 :                 double nValue = 0;
     335           0 :                 aValue >>= nValue;
     336           0 :                 if ( m_xCell.is() )
     337           0 :                     m_xCell->setValue( nValue );
     338             :             }
     339           0 :             break;
     340             : 
     341             :         case TypeClass_LONG:
     342             :             {
     343             :                 OSL_ENSURE( m_xCell.is(), "OCellValueBinding::setValue: don't have a double value supplier!" );
     344             : 
     345           0 :                 sal_Int32 nValue = 0;
     346           0 :                 aValue >>= nValue;      // list index from control layer (0-based)
     347           0 :                 ++nValue;               // the list position value in the cell is 1-based
     348           0 :                 if ( m_xCell.is() )
     349           0 :                     m_xCell->setValue( nValue );
     350             :             }
     351           0 :             break;
     352             : 
     353             :         case TypeClass_VOID:
     354             :             {
     355             :                 // #N/A error value can only be set using XCellRangeData
     356             : 
     357           0 :                 Reference<XCellRangeData> xData( m_xCell, UNO_QUERY );
     358             :                 OSL_ENSURE( xData.is(), "OCellValueBinding::setValue: don't have XCellRangeData!" );
     359           0 :                 if ( xData.is() )
     360             :                 {
     361           0 :                     Sequence<Any> aInner(1);                            // one empty element
     362           0 :                     Sequence< Sequence<Any> > aOuter( &aInner, 1 );     // one row
     363           0 :                     xData->setDataArray( aOuter );
     364           0 :                 }
     365             :             }
     366           0 :             break;
     367             : 
     368             :         default:
     369             :             OSL_FAIL( "OCellValueBinding::setValue: unreachable code!" );
     370             :                 // a type other than double and string should never have survived the checkValueType
     371             :                 // above
     372             :         }
     373           0 :     }
     374             : 
     375           0 :     void OCellValueBinding::setBooleanFormat()
     376             :     {
     377             :         // set boolean number format if not already set
     378             : 
     379           0 :         OUString sPropName( "NumberFormat" );
     380           0 :         Reference<XPropertySet> xCellProp( m_xCell, UNO_QUERY );
     381           0 :         Reference<XNumberFormatsSupplier> xSupplier( m_xDocument, UNO_QUERY );
     382           0 :         if ( xSupplier.is() && xCellProp.is() )
     383             :         {
     384           0 :             Reference<XNumberFormats> xFormats(xSupplier->getNumberFormats());
     385           0 :             Reference<XNumberFormatTypes> xTypes( xFormats, UNO_QUERY );
     386           0 :             if ( xTypes.is() )
     387             :             {
     388           0 :                 Locale aLocale;
     389           0 :                 sal_Bool bWasBoolean = false;
     390             : 
     391           0 :                 sal_Int32 nOldIndex = ::comphelper::getINT32( xCellProp->getPropertyValue( sPropName ) );
     392           0 :                 Reference<XPropertySet> xOldFormat;
     393             :                 try
     394             :                 {
     395           0 :                     xOldFormat.set(xFormats->getByKey( nOldIndex ));
     396             :                 }
     397           0 :                 catch ( Exception& )
     398             :                 {
     399             :                     // non-existing format - can happen, use defaults
     400             :                 }
     401           0 :                 if ( xOldFormat.is() )
     402             :                 {
     403             :                     // use the locale of the existing format
     404           0 :                     xOldFormat->getPropertyValue("Locale") >>= aLocale;
     405             : 
     406             :                     sal_Int16 nOldType = ::comphelper::getINT16(
     407           0 :                         xOldFormat->getPropertyValue("Type") );
     408           0 :                     if ( nOldType & NumberFormat::LOGICAL )
     409           0 :                         bWasBoolean = sal_True;
     410             :                 }
     411             : 
     412           0 :                 if ( !bWasBoolean )
     413             :                 {
     414           0 :                     sal_Int32 nNewIndex = xTypes->getStandardFormat( NumberFormat::LOGICAL, aLocale );
     415           0 :                     xCellProp->setPropertyValue( sPropName, makeAny( nNewIndex ) );
     416           0 :                 }
     417           0 :             }
     418           0 :         }
     419           0 :     }
     420             : 
     421             : 
     422           7 :     void OCellValueBinding::checkDisposed( ) const SAL_THROW( ( DisposedException ) )
     423             :     {
     424           7 :         if ( OCellValueBinding_Base::rBHelper.bInDispose || OCellValueBinding_Base::rBHelper.bDisposed )
     425           0 :             throw DisposedException();
     426             :             // TODO: is it worth having an error message here?
     427           7 :     }
     428             : 
     429             : 
     430           7 :     void OCellValueBinding::checkInitialized() SAL_THROW( ( RuntimeException ) )
     431             :     {
     432           7 :         if ( !m_bInitialized )
     433           0 :             throw RuntimeException();
     434             :             // TODO: error message
     435           7 :     }
     436             : 
     437             : 
     438           1 :     void OCellValueBinding::checkValueType( const Type& _rType ) const SAL_THROW( ( IncompatibleTypesException ) )
     439             :     {
     440           1 :         OCellValueBinding* pNonConstThis = const_cast< OCellValueBinding* >( this );
     441           1 :         if ( !pNonConstThis->supportsType( _rType ) )
     442             :         {
     443           0 :             OUString sMessage( "The given type (" );
     444           0 :             sMessage += _rType.getTypeName();
     445           0 :             sMessage += ") is not supported by this binding.";
     446             :                 // TODO: localize this error message
     447             : 
     448           0 :             throw IncompatibleTypesException( sMessage, *pNonConstThis );
     449             :                 // TODO: alternatively use a type converter service for this?
     450             :         }
     451           1 :     }
     452             : 
     453           0 :     OUString SAL_CALL OCellValueBinding::getImplementationName(  ) throw (RuntimeException, std::exception)
     454             :     {
     455           0 :         return OUString( "com.sun.star.comp.sheet.OCellValueBinding" );
     456             :     }
     457             : 
     458           0 :     sal_Bool SAL_CALL OCellValueBinding::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
     459             :     {
     460           0 :         return cppu::supportsService(this, _rServiceName);
     461             :     }
     462             : 
     463           0 :     Sequence< OUString > SAL_CALL OCellValueBinding::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     464             :     {
     465           0 :         Sequence< OUString > aServices( m_bListPos ? 3 : 2 );
     466           0 :         aServices[ 0 ] = "com.sun.star.table.CellValueBinding";
     467           0 :         aServices[ 1 ] = "com.sun.star.form.binding.ValueBinding";
     468           0 :         if ( m_bListPos )
     469           0 :             aServices[ 2 ] = "com.sun.star.table.ListPositionCellBinding";
     470           0 :         return aServices;
     471             :     }
     472             : 
     473           1 :     void SAL_CALL OCellValueBinding::addModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException, std::exception)
     474             :     {
     475           1 :        if ( _rxListener.is() )
     476           1 :            m_aModifyListeners.addInterface( _rxListener );
     477           1 :     }
     478             : 
     479             : 
     480           1 :     void SAL_CALL OCellValueBinding::removeModifyListener( const Reference< XModifyListener >& _rxListener ) throw (RuntimeException, std::exception)
     481             :     {
     482           1 :        if ( _rxListener.is() )
     483           1 :            m_aModifyListeners.removeInterface( _rxListener );
     484           1 :     }
     485             : 
     486             : 
     487           0 :     void OCellValueBinding::notifyModified()
     488             :     {
     489           0 :         EventObject aEvent;
     490           0 :         aEvent.Source.set(*this);
     491             : 
     492           0 :         ::cppu::OInterfaceIteratorHelper aIter( m_aModifyListeners );
     493           0 :         while ( aIter.hasMoreElements() )
     494             :         {
     495             :             try
     496             :             {
     497           0 :                 static_cast< XModifyListener* >( aIter.next() )->modified( aEvent );
     498             :             }
     499           0 :             catch( const RuntimeException& )
     500             :             {
     501             :                 // silent this
     502             :             }
     503           0 :             catch( const Exception& )
     504             :             {
     505             :                 OSL_FAIL( "OCellValueBinding::notifyModified: caught a (non-runtime) exception!" );
     506             :             }
     507           0 :         }
     508           0 :     }
     509             : 
     510             : 
     511           0 :     void SAL_CALL OCellValueBinding::modified( const EventObject& /* aEvent */ ) throw (RuntimeException, std::exception)
     512             :     {
     513           0 :         notifyModified();
     514           0 :     }
     515             : 
     516             : 
     517           1 :     void SAL_CALL OCellValueBinding::disposing( const EventObject& aEvent ) throw (RuntimeException, std::exception)
     518             :     {
     519           1 :         Reference<XInterface> xCellInt( m_xCell, UNO_QUERY );
     520           1 :         if ( xCellInt == aEvent.Source )
     521             :         {
     522             :             // release references to cell object
     523           1 :             m_xCell.clear();
     524           1 :             m_xCellText.clear();
     525           1 :         }
     526           1 :     }
     527             : 
     528             : 
     529           1 :     void SAL_CALL OCellValueBinding::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException, std::exception)
     530             :     {
     531           1 :         if ( m_bInitialized )
     532           0 :             throw Exception();
     533             :             // TODO: error message
     534             : 
     535             :         // get the cell address
     536           1 :         CellAddress aAddress;
     537           1 :         sal_Bool bFoundAddress = false;
     538             : 
     539           1 :         const Any* pLoop = _rArguments.getConstArray();
     540           1 :         const Any* pLoopEnd = _rArguments.getConstArray() + _rArguments.getLength();
     541           2 :         for ( ; ( pLoop != pLoopEnd ) && !bFoundAddress; ++pLoop )
     542             :         {
     543           1 :             NamedValue aValue;
     544           1 :             if ( *pLoop >>= aValue )
     545             :             {
     546           1 :                 if ( aValue.Name == "BoundCell" )
     547             :                 {
     548           1 :                     if ( aValue.Value >>= aAddress )
     549           1 :                         bFoundAddress = sal_True;
     550             :                 }
     551             :             }
     552           1 :         }
     553             : 
     554           1 :         if ( !bFoundAddress )
     555             :             // TODO: error message
     556           0 :             throw Exception();
     557             : 
     558             :         // get the cell object
     559             :         try
     560             :         {
     561             :             // first the sheets collection
     562           1 :             Reference< XIndexAccess > xSheets;
     563           1 :             if ( m_xDocument.is() )
     564           1 :                 xSheets.set(xSheets.query( m_xDocument->getSheets( ) ));
     565             :             OSL_ENSURE( xSheets.is(), "OCellValueBinding::initialize: could not retrieve the sheets!" );
     566             : 
     567           1 :             if ( xSheets.is() )
     568             :             {
     569             :                 // the concrete sheet
     570           1 :                 Reference< XCellRange > xSheet(xSheets->getByIndex( aAddress.Sheet ), UNO_QUERY);
     571             :                 OSL_ENSURE( xSheet.is(), "OCellValueBinding::initialize: NULL sheet, but no exception!" );
     572             : 
     573             :                 // the concrete cell
     574           1 :                 if ( xSheet.is() )
     575             :                 {
     576           1 :                     m_xCell.set(xSheet->getCellByPosition( aAddress.Column, aAddress.Row ));
     577           1 :                     Reference< XCellAddressable > xAddressAccess( m_xCell, UNO_QUERY );
     578           1 :                     OSL_ENSURE( xAddressAccess.is(), "OCellValueBinding::initialize: either NULL cell, or cell without address access!" );
     579           1 :                 }
     580           1 :             }
     581             :         }
     582           0 :         catch( const Exception& )
     583             :         {
     584             :             OSL_FAIL( "OCellValueBinding::initialize: caught an exception while retrieving the cell object!" );
     585             :         }
     586             : 
     587           1 :         if ( !m_xCell.is() )
     588           0 :             throw Exception();
     589             :             // TODO error message
     590             : 
     591           1 :         m_xCellText.set(m_xCellText.query( m_xCell ));
     592             : 
     593           1 :         Reference<XModifyBroadcaster> xBroadcaster( m_xCell, UNO_QUERY );
     594           1 :         if ( xBroadcaster.is() )
     595             :         {
     596           1 :             xBroadcaster->addModifyListener( this );
     597             :         }
     598             : 
     599             :         // TODO: add as XEventListener to the cell, so we get notified when it dies,
     600             :         // and can dispose ourself then
     601             : 
     602             :         // TODO: somehow add as listener so we get notified when the address of the cell changes
     603             :         // We need to forward this as change in our BoundCell property to our property change listeners
     604             : 
     605             :         // TODO: be an XModifyBroadcaster, so that changes in our cell can be notified
     606             :         // to the BindableValue which is/will be bound to this instance.
     607             : 
     608           1 :         m_bInitialized = true;
     609             :         // TODO: place your code here
     610           1 :     }
     611             : 
     612             : }   // namespace calc
     613             : 
     614             : 
     615             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10