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