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

Generated by: LCOV version 1.11