1*2a97ec55SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2a97ec55SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2a97ec55SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2a97ec55SAndrew Rist * distributed with this work for additional information 6*2a97ec55SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2a97ec55SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2a97ec55SAndrew Rist * "License"); you may not use this file except in compliance 9*2a97ec55SAndrew Rist * with the License. You may obtain a copy of the License at 10*2a97ec55SAndrew Rist * 11*2a97ec55SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*2a97ec55SAndrew Rist * 13*2a97ec55SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2a97ec55SAndrew Rist * software distributed under the License is distributed on an 15*2a97ec55SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2a97ec55SAndrew Rist * KIND, either express or implied. See the License for the 17*2a97ec55SAndrew Rist * specific language governing permissions and limitations 18*2a97ec55SAndrew Rist * under the License. 19*2a97ec55SAndrew Rist * 20*2a97ec55SAndrew Rist *************************************************************/ 21*2a97ec55SAndrew Rist 22*2a97ec55SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_extensions.hxx" 26cdf0e10cSrcweir #include "cellbindinghelper.hxx" 27cdf0e10cSrcweir #include <com/sun/star/form/binding/XBindableValue.hpp> 28cdf0e10cSrcweir #include <com/sun/star/form/binding/XListEntrySink.hpp> 29cdf0e10cSrcweir #include <com/sun/star/form/FormComponentType.hpp> 30cdf0e10cSrcweir #include <com/sun/star/form/XGridColumnFactory.hpp> 31cdf0e10cSrcweir #include <com/sun/star/container/XChild.hpp> 32cdf0e10cSrcweir #include <com/sun/star/container/XNamed.hpp> 33cdf0e10cSrcweir #include <com/sun/star/drawing/XDrawPageSupplier.hpp> 34cdf0e10cSrcweir #include <com/sun/star/table/XCellRange.hpp> 35cdf0e10cSrcweir #include <com/sun/star/form/XFormsSupplier.hpp> 36cdf0e10cSrcweir #include <com/sun/star/form/XForm.hpp> 37cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp> 38cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp> 39cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp> 40cdf0e10cSrcweir #include <com/sun/star/sheet/XSpreadsheet.hpp> 41cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx> 42cdf0e10cSrcweir #include <osl/diagnose.h> 43cdf0e10cSrcweir #include <tools/diagnose_ex.h> 44cdf0e10cSrcweir #include "formstrings.hxx" 45cdf0e10cSrcweir 46cdf0e10cSrcweir #include <functional> 47cdf0e10cSrcweir #include <algorithm> 48cdf0e10cSrcweir 49cdf0e10cSrcweir //............................................................................ 50cdf0e10cSrcweir namespace pcr 51cdf0e10cSrcweir { 52cdf0e10cSrcweir //............................................................................ 53cdf0e10cSrcweir 54cdf0e10cSrcweir using namespace ::com::sun::star::uno; 55cdf0e10cSrcweir using namespace ::com::sun::star::beans; 56cdf0e10cSrcweir using namespace ::com::sun::star::frame; 57cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 58cdf0e10cSrcweir using namespace ::com::sun::star::container; 59cdf0e10cSrcweir using namespace ::com::sun::star::drawing; 60cdf0e10cSrcweir using namespace ::com::sun::star::table; 61cdf0e10cSrcweir using namespace ::com::sun::star::form; 62cdf0e10cSrcweir using namespace ::com::sun::star::lang; 63cdf0e10cSrcweir using namespace ::com::sun::star::i18n; 64cdf0e10cSrcweir using namespace ::com::sun::star::form::binding; 65cdf0e10cSrcweir 66cdf0e10cSrcweir namespace 67cdf0e10cSrcweir { 68cdf0e10cSrcweir //.................................................................... 69cdf0e10cSrcweir struct StringCompare : public ::std::unary_function< ::rtl::OUString, bool > 70cdf0e10cSrcweir { 71cdf0e10cSrcweir private: 72cdf0e10cSrcweir ::rtl::OUString m_sReference; 73cdf0e10cSrcweir 74cdf0e10cSrcweir public: StringComparepcr::__anon03035f890111::StringCompare75cdf0e10cSrcweir StringCompare( const ::rtl::OUString& _rReference ) : m_sReference( _rReference ) { } 76cdf0e10cSrcweir operator ()pcr::__anon03035f890111::StringCompare77cdf0e10cSrcweir inline bool operator()( const ::rtl::OUString& _rCompare ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir return ( _rCompare == m_sReference ) ? true : false; 80cdf0e10cSrcweir } 81cdf0e10cSrcweir }; 82cdf0e10cSrcweir } 83cdf0e10cSrcweir 84cdf0e10cSrcweir //======================================================================== 85cdf0e10cSrcweir //= CellBindingHelper 86cdf0e10cSrcweir //======================================================================== 87cdf0e10cSrcweir //------------------------------------------------------------------------ CellBindingHelper(const Reference<XPropertySet> & _rxControlModel,const Reference<XModel> & _rxContextDocument)88cdf0e10cSrcweir CellBindingHelper::CellBindingHelper( const Reference< XPropertySet >& _rxControlModel, const Reference< XModel >& _rxContextDocument ) 89cdf0e10cSrcweir :m_xControlModel( _rxControlModel ) 90cdf0e10cSrcweir { 91cdf0e10cSrcweir OSL_ENSURE( m_xControlModel.is(), "CellBindingHelper::CellBindingHelper: invalid control model!" ); 92cdf0e10cSrcweir 93cdf0e10cSrcweir m_xDocument = m_xDocument.query( _rxContextDocument ); 94cdf0e10cSrcweir OSL_ENSURE( m_xDocument.is(), "CellBindingHelper::CellBindingHelper: This is no spreadsheet document!" ); 95cdf0e10cSrcweir 96cdf0e10cSrcweir OSL_ENSURE( isSpreadsheetDocumentWhichSupplies( SERVICE_ADDRESS_CONVERSION ), 97cdf0e10cSrcweir "CellBindingHelper::CellBindingHelper: the document cannot convert address representations!" ); 98cdf0e10cSrcweir } 99cdf0e10cSrcweir 100cdf0e10cSrcweir //------------------------------------------------------------------------ isSpreadsheetDocument(const Reference<XModel> & _rxContextDocument)101cdf0e10cSrcweir sal_Bool CellBindingHelper::isSpreadsheetDocument( const Reference< XModel >& _rxContextDocument ) 102cdf0e10cSrcweir { 103cdf0e10cSrcweir return Reference< XSpreadsheetDocument >::query( _rxContextDocument ).is(); 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir //------------------------------------------------------------------------ getControlSheetIndex(Reference<XSpreadsheet> & _out_rxSheet) const107cdf0e10cSrcweir sal_Int16 CellBindingHelper::getControlSheetIndex( Reference< XSpreadsheet >& _out_rxSheet ) const 108cdf0e10cSrcweir { 109cdf0e10cSrcweir sal_Int16 nSheetIndex = -1; 110cdf0e10cSrcweir // every sheet has a draw page, and every draw page has a forms collection. 111cdf0e10cSrcweir // Our control, OTOH, belongs to a forms collection. Match these ... 112cdf0e10cSrcweir try 113cdf0e10cSrcweir { 114cdf0e10cSrcweir // for determining the draw page, we need the forms collection which 115cdf0e10cSrcweir // the object belongs to. This is the first object up the hierarchy which is 116cdf0e10cSrcweir // *no* XForm (and, well, no XGridColumnFactory) 117cdf0e10cSrcweir Reference< XChild > xCheck( m_xControlModel, UNO_QUERY ); 118cdf0e10cSrcweir Reference< XForm > xParentAsForm; if ( xCheck.is() ) xParentAsForm = xParentAsForm.query( xCheck->getParent() ); 119cdf0e10cSrcweir Reference< XGridColumnFactory > xParentAsGrid; if ( xCheck.is() ) xParentAsGrid = xParentAsGrid.query( xCheck->getParent() ); 120cdf0e10cSrcweir 121cdf0e10cSrcweir while ( ( xParentAsForm.is() || xParentAsGrid.is() ) && xCheck.is() ) 122cdf0e10cSrcweir { 123cdf0e10cSrcweir xCheck = xCheck.query( xCheck->getParent() ); 124cdf0e10cSrcweir xParentAsForm = xParentAsForm.query( xCheck.is() ? xCheck->getParent() : (Reference< XInterface >) Reference< XForm >() ); 125cdf0e10cSrcweir xParentAsGrid = xParentAsGrid.query( xCheck.is() ? xCheck->getParent() : (Reference< XInterface >) Reference< XGridColumnFactory >() ); 126cdf0e10cSrcweir } 127cdf0e10cSrcweir Reference< XInterface > xFormsCollection( xCheck.is() ? xCheck->getParent() : Reference< XInterface >() ); 128cdf0e10cSrcweir 129cdf0e10cSrcweir // now iterate through the sheets 130cdf0e10cSrcweir Reference< XIndexAccess > xSheets( m_xDocument->getSheets(), UNO_QUERY ); 131cdf0e10cSrcweir if ( xSheets.is() && xFormsCollection.is() ) 132cdf0e10cSrcweir { 133cdf0e10cSrcweir for ( sal_Int32 i = 0; i < xSheets->getCount(); ++i ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir Reference< XDrawPageSupplier > xSuppPage( xSheets->getByIndex( i ), UNO_QUERY_THROW ); 136cdf0e10cSrcweir Reference< XFormsSupplier > xSuppForms( xSuppPage->getDrawPage(), UNO_QUERY_THROW ); 137cdf0e10cSrcweir 138cdf0e10cSrcweir if ( xSuppForms->getForms() == xFormsCollection ) 139cdf0e10cSrcweir { // found it 140cdf0e10cSrcweir nSheetIndex = (sal_Int16)i; 141cdf0e10cSrcweir _out_rxSheet.set( xSuppPage, UNO_QUERY_THROW ); 142cdf0e10cSrcweir break; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir } 145cdf0e10cSrcweir } 146cdf0e10cSrcweir } 147cdf0e10cSrcweir catch( const Exception& ) 148cdf0e10cSrcweir { 149cdf0e10cSrcweir DBG_UNHANDLED_EXCEPTION(); 150cdf0e10cSrcweir } 151cdf0e10cSrcweir 152cdf0e10cSrcweir return nSheetIndex; 153cdf0e10cSrcweir } 154cdf0e10cSrcweir 155cdf0e10cSrcweir //------------------------------------------------------------------------ convertStringAddress(const::rtl::OUString & _rAddressDescription,CellAddress & _rAddress) const156cdf0e10cSrcweir bool CellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription, CellAddress& /* [out] */ _rAddress ) const 157cdf0e10cSrcweir { 158cdf0e10cSrcweir Any aAddress; 159cdf0e10cSrcweir return doConvertAddressRepresentations( 160cdf0e10cSrcweir PROPERTY_UI_REPRESENTATION, 161cdf0e10cSrcweir makeAny( _rAddressDescription ), 162cdf0e10cSrcweir PROPERTY_ADDRESS, 163cdf0e10cSrcweir aAddress, 164cdf0e10cSrcweir false 165cdf0e10cSrcweir ) 166cdf0e10cSrcweir && ( aAddress >>= _rAddress ); 167cdf0e10cSrcweir } 168cdf0e10cSrcweir 169cdf0e10cSrcweir //------------------------------------------------------------------------ doConvertAddressRepresentations(const::rtl::OUString & _rInputProperty,const Any & _rInputValue,const::rtl::OUString & _rOutputProperty,Any & _rOutputValue,bool _bIsRange) const170cdf0e10cSrcweir bool CellBindingHelper::doConvertAddressRepresentations( const ::rtl::OUString& _rInputProperty, const Any& _rInputValue, 171cdf0e10cSrcweir const ::rtl::OUString& _rOutputProperty, Any& _rOutputValue, bool _bIsRange ) const SAL_THROW(()) 172cdf0e10cSrcweir { 173cdf0e10cSrcweir bool bSuccess = false; 174cdf0e10cSrcweir 175cdf0e10cSrcweir Reference< XPropertySet > xConverter( 176cdf0e10cSrcweir createDocumentDependentInstance( 177cdf0e10cSrcweir _bIsRange ? SERVICE_RANGEADDRESS_CONVERSION : SERVICE_ADDRESS_CONVERSION, 178cdf0e10cSrcweir ::rtl::OUString(), 179cdf0e10cSrcweir Any() 180cdf0e10cSrcweir ), 181cdf0e10cSrcweir UNO_QUERY 182cdf0e10cSrcweir ); 183cdf0e10cSrcweir OSL_ENSURE( xConverter.is(), "CellBindingHelper::doConvertAddressRepresentations: could not get a converter service!" ); 184cdf0e10cSrcweir if ( xConverter.is() ) 185cdf0e10cSrcweir { 186cdf0e10cSrcweir try 187cdf0e10cSrcweir { 188cdf0e10cSrcweir Reference< XSpreadsheet > xSheet; 189cdf0e10cSrcweir xConverter->setPropertyValue( PROPERTY_REFERENCE_SHEET, makeAny( (sal_Int32)getControlSheetIndex( xSheet ) ) ); 190cdf0e10cSrcweir xConverter->setPropertyValue( _rInputProperty, _rInputValue ); 191cdf0e10cSrcweir _rOutputValue = xConverter->getPropertyValue( _rOutputProperty ); 192cdf0e10cSrcweir bSuccess = true; 193cdf0e10cSrcweir } 194cdf0e10cSrcweir catch( const Exception& ) 195cdf0e10cSrcweir { 196cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::doConvertAddressRepresentations: caught an exception!" ); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir } 199cdf0e10cSrcweir 200cdf0e10cSrcweir return bSuccess; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir //------------------------------------------------------------------------ convertStringAddress(const::rtl::OUString & _rAddressDescription,CellRangeAddress & _rAddress) const204cdf0e10cSrcweir bool CellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription, 205cdf0e10cSrcweir CellRangeAddress& /* [out] */ _rAddress ) const 206cdf0e10cSrcweir { 207cdf0e10cSrcweir Any aAddress; 208cdf0e10cSrcweir return doConvertAddressRepresentations( 209cdf0e10cSrcweir PROPERTY_UI_REPRESENTATION, 210cdf0e10cSrcweir makeAny( _rAddressDescription ), 211cdf0e10cSrcweir PROPERTY_ADDRESS, 212cdf0e10cSrcweir aAddress, 213cdf0e10cSrcweir true 214cdf0e10cSrcweir ) 215cdf0e10cSrcweir && ( aAddress >>= _rAddress ); 216cdf0e10cSrcweir } 217cdf0e10cSrcweir 218cdf0e10cSrcweir //------------------------------------------------------------------------ createCellBindingFromAddress(const CellAddress & _rAddress,bool _bSupportIntegerExchange) const219cdf0e10cSrcweir Reference< XValueBinding > CellBindingHelper::createCellBindingFromAddress( const CellAddress& _rAddress, bool _bSupportIntegerExchange ) const 220cdf0e10cSrcweir { 221cdf0e10cSrcweir Reference< XValueBinding > xBinding( createDocumentDependentInstance( 222cdf0e10cSrcweir _bSupportIntegerExchange ? SERVICE_SHEET_CELL_INT_BINDING : SERVICE_SHEET_CELL_BINDING, 223cdf0e10cSrcweir PROPERTY_BOUND_CELL, 224cdf0e10cSrcweir makeAny( _rAddress ) 225cdf0e10cSrcweir ), UNO_QUERY ); 226cdf0e10cSrcweir 227cdf0e10cSrcweir return xBinding; 228cdf0e10cSrcweir } 229cdf0e10cSrcweir 230cdf0e10cSrcweir //------------------------------------------------------------------------ createCellBindingFromStringAddress(const::rtl::OUString & _rAddress,bool _bSupportIntegerExchange) const231cdf0e10cSrcweir Reference< XValueBinding > CellBindingHelper::createCellBindingFromStringAddress( const ::rtl::OUString& _rAddress, bool _bSupportIntegerExchange ) const 232cdf0e10cSrcweir { 233cdf0e10cSrcweir Reference< XValueBinding > xBinding; 234cdf0e10cSrcweir if ( !m_xDocument.is() ) 235cdf0e10cSrcweir // very bad ... 236cdf0e10cSrcweir return xBinding; 237cdf0e10cSrcweir 238cdf0e10cSrcweir // get the UNO representation of the address 239cdf0e10cSrcweir CellAddress aAddress; 240cdf0e10cSrcweir if ( !_rAddress.getLength() || !convertStringAddress( _rAddress, aAddress ) ) 241cdf0e10cSrcweir return xBinding; 242cdf0e10cSrcweir 243cdf0e10cSrcweir return createCellBindingFromAddress( aAddress, _bSupportIntegerExchange ); 244cdf0e10cSrcweir } 245cdf0e10cSrcweir 246cdf0e10cSrcweir //------------------------------------------------------------------------ createCellListSourceFromStringAddress(const::rtl::OUString & _rAddress) const247cdf0e10cSrcweir Reference< XListEntrySource > CellBindingHelper::createCellListSourceFromStringAddress( const ::rtl::OUString& _rAddress ) const 248cdf0e10cSrcweir { 249cdf0e10cSrcweir Reference< XListEntrySource > xSource; 250cdf0e10cSrcweir 251cdf0e10cSrcweir CellRangeAddress aRangeAddress; 252cdf0e10cSrcweir if ( !_rAddress.getLength() || !convertStringAddress( _rAddress, aRangeAddress ) ) 253cdf0e10cSrcweir return xSource; 254cdf0e10cSrcweir 255cdf0e10cSrcweir // create a range object for this address 256cdf0e10cSrcweir xSource = xSource.query( createDocumentDependentInstance( 257cdf0e10cSrcweir SERVICE_SHEET_CELLRANGE_LISTSOURCE, 258cdf0e10cSrcweir PROPERTY_LIST_CELL_RANGE, 259cdf0e10cSrcweir makeAny( aRangeAddress ) 260cdf0e10cSrcweir ) ); 261cdf0e10cSrcweir 262cdf0e10cSrcweir return xSource; 263cdf0e10cSrcweir } 264cdf0e10cSrcweir 265cdf0e10cSrcweir //------------------------------------------------------------------------ createDocumentDependentInstance(const::rtl::OUString & _rService,const::rtl::OUString & _rArgumentName,const Any & _rArgumentValue) const266cdf0e10cSrcweir Reference< XInterface > CellBindingHelper::createDocumentDependentInstance( const ::rtl::OUString& _rService, const ::rtl::OUString& _rArgumentName, 267cdf0e10cSrcweir const Any& _rArgumentValue ) const 268cdf0e10cSrcweir { 269cdf0e10cSrcweir Reference< XInterface > xReturn; 270cdf0e10cSrcweir 271cdf0e10cSrcweir Reference< XMultiServiceFactory > xDocumentFactory( m_xDocument, UNO_QUERY ); 272cdf0e10cSrcweir OSL_ENSURE( xDocumentFactory.is(), "CellBindingHelper::createDocumentDependentInstance: no document service factory!" ); 273cdf0e10cSrcweir if ( xDocumentFactory.is() ) 274cdf0e10cSrcweir { 275cdf0e10cSrcweir try 276cdf0e10cSrcweir { 277cdf0e10cSrcweir if ( _rArgumentName.getLength() ) 278cdf0e10cSrcweir { 279cdf0e10cSrcweir NamedValue aArg; 280cdf0e10cSrcweir aArg.Name = _rArgumentName; 281cdf0e10cSrcweir aArg.Value = _rArgumentValue; 282cdf0e10cSrcweir 283cdf0e10cSrcweir Sequence< Any > aArgs( 1 ); 284cdf0e10cSrcweir aArgs[ 0 ] <<= aArg; 285cdf0e10cSrcweir 286cdf0e10cSrcweir xReturn = xDocumentFactory->createInstanceWithArguments( _rService, aArgs ); 287cdf0e10cSrcweir } 288cdf0e10cSrcweir else 289cdf0e10cSrcweir { 290cdf0e10cSrcweir xReturn = xDocumentFactory->createInstance( _rService ); 291cdf0e10cSrcweir } 292cdf0e10cSrcweir } 293cdf0e10cSrcweir catch ( const Exception& ) 294cdf0e10cSrcweir { 295cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::createDocumentDependentInstance: could not create the binding at the document!" ); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir } 298cdf0e10cSrcweir return xReturn; 299cdf0e10cSrcweir } 300cdf0e10cSrcweir 301cdf0e10cSrcweir //------------------------------------------------------------------------ getAddressFromCellBinding(const Reference<XValueBinding> & _rxBinding,CellAddress & _rAddress) const302cdf0e10cSrcweir bool CellBindingHelper::getAddressFromCellBinding( 303cdf0e10cSrcweir const Reference< XValueBinding >& _rxBinding, CellAddress& _rAddress ) const 304cdf0e10cSrcweir { 305cdf0e10cSrcweir OSL_PRECOND( !_rxBinding.is() || isCellBinding( _rxBinding ), "CellBindingHelper::getAddressFromCellBinding: this is no cell binding!" ); 306cdf0e10cSrcweir 307cdf0e10cSrcweir bool bReturn = false; 308cdf0e10cSrcweir if ( !m_xDocument.is() ) 309cdf0e10cSrcweir // very bad ... 310cdf0e10cSrcweir return bReturn; 311cdf0e10cSrcweir 312cdf0e10cSrcweir try 313cdf0e10cSrcweir { 314cdf0e10cSrcweir Reference< XPropertySet > xBindingProps( _rxBinding, UNO_QUERY ); 315cdf0e10cSrcweir OSL_ENSURE( xBindingProps.is() || !_rxBinding.is(), "CellBindingHelper::getAddressFromCellBinding: no property set for the binding!" ); 316cdf0e10cSrcweir if ( xBindingProps.is() ) 317cdf0e10cSrcweir { 318cdf0e10cSrcweir CellAddress aAddress; 319cdf0e10cSrcweir bReturn = (bool)( xBindingProps->getPropertyValue( PROPERTY_BOUND_CELL ) >>= _rAddress ); 320cdf0e10cSrcweir } 321cdf0e10cSrcweir } 322cdf0e10cSrcweir catch( const Exception& ) 323cdf0e10cSrcweir { 324cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::getAddressFromCellBinding: caught an exception!" ); 325cdf0e10cSrcweir } 326cdf0e10cSrcweir 327cdf0e10cSrcweir return bReturn; 328cdf0e10cSrcweir } 329cdf0e10cSrcweir 330cdf0e10cSrcweir //------------------------------------------------------------------------ getStringAddressFromCellBinding(const Reference<XValueBinding> & _rxBinding) const331cdf0e10cSrcweir ::rtl::OUString CellBindingHelper::getStringAddressFromCellBinding( const Reference< XValueBinding >& _rxBinding ) const 332cdf0e10cSrcweir { 333cdf0e10cSrcweir CellAddress aAddress; 334cdf0e10cSrcweir ::rtl::OUString sAddress; 335cdf0e10cSrcweir if ( getAddressFromCellBinding( _rxBinding, aAddress ) ) 336cdf0e10cSrcweir { 337cdf0e10cSrcweir Any aStringAddress; 338cdf0e10cSrcweir doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aAddress ), 339cdf0e10cSrcweir PROPERTY_UI_REPRESENTATION, aStringAddress, false ); 340cdf0e10cSrcweir 341cdf0e10cSrcweir aStringAddress >>= sAddress; 342cdf0e10cSrcweir } 343cdf0e10cSrcweir 344cdf0e10cSrcweir return sAddress; 345cdf0e10cSrcweir } 346cdf0e10cSrcweir 347cdf0e10cSrcweir //------------------------------------------------------------------------ getStringAddressFromCellListSource(const Reference<XListEntrySource> & _rxSource) const348cdf0e10cSrcweir ::rtl::OUString CellBindingHelper::getStringAddressFromCellListSource( const Reference< XListEntrySource >& _rxSource ) const 349cdf0e10cSrcweir { 350cdf0e10cSrcweir OSL_PRECOND( !_rxSource.is() || isCellRangeListSource( _rxSource ), "CellBindingHelper::getStringAddressFromCellListSource: this is no cell list source!" ); 351cdf0e10cSrcweir 352cdf0e10cSrcweir ::rtl::OUString sAddress; 353cdf0e10cSrcweir if ( !m_xDocument.is() ) 354cdf0e10cSrcweir // very bad ... 355cdf0e10cSrcweir return sAddress; 356cdf0e10cSrcweir 357cdf0e10cSrcweir try 358cdf0e10cSrcweir { 359cdf0e10cSrcweir Reference< XPropertySet > xSourceProps( _rxSource, UNO_QUERY ); 360cdf0e10cSrcweir OSL_ENSURE( xSourceProps.is() || !_rxSource.is(), "CellBindingHelper::getStringAddressFromCellListSource: no property set for the list source!" ); 361cdf0e10cSrcweir if ( xSourceProps.is() ) 362cdf0e10cSrcweir { 363cdf0e10cSrcweir CellRangeAddress aRangeAddress; 364cdf0e10cSrcweir xSourceProps->getPropertyValue( PROPERTY_LIST_CELL_RANGE ) >>= aRangeAddress; 365cdf0e10cSrcweir 366cdf0e10cSrcweir Any aStringAddress; 367cdf0e10cSrcweir doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aRangeAddress ), 368cdf0e10cSrcweir PROPERTY_UI_REPRESENTATION, aStringAddress, true ); 369cdf0e10cSrcweir aStringAddress >>= sAddress; 370cdf0e10cSrcweir } 371cdf0e10cSrcweir } 372cdf0e10cSrcweir catch( const Exception& ) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::getStringAddressFromCellListSource: caught an exception!" ); 375cdf0e10cSrcweir } 376cdf0e10cSrcweir 377cdf0e10cSrcweir return sAddress; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir 380cdf0e10cSrcweir //------------------------------------------------------------------------ isSpreadsheetDocumentWhichSupplies(const::rtl::OUString & _rService) const381cdf0e10cSrcweir bool CellBindingHelper::isSpreadsheetDocumentWhichSupplies( const ::rtl::OUString& _rService ) const 382cdf0e10cSrcweir { 383cdf0e10cSrcweir bool bYesItIs = false; 384cdf0e10cSrcweir 385cdf0e10cSrcweir Reference< XServiceInfo > xSI( m_xDocument, UNO_QUERY ); 386cdf0e10cSrcweir if ( xSI.is() && xSI->supportsService( SERVICE_SPREADSHEET_DOCUMENT ) ) 387cdf0e10cSrcweir { 388cdf0e10cSrcweir Reference< XMultiServiceFactory > xDocumentFactory( m_xDocument, UNO_QUERY ); 389cdf0e10cSrcweir OSL_ENSURE( xDocumentFactory.is(), "CellBindingHelper::isSpreadsheetDocumentWhichSupplies: spreadsheet document, but no factory?" ); 390cdf0e10cSrcweir 391cdf0e10cSrcweir Sequence< ::rtl::OUString > aAvailableServices; 392cdf0e10cSrcweir if ( xDocumentFactory.is() ) 393cdf0e10cSrcweir aAvailableServices = xDocumentFactory->getAvailableServiceNames( ); 394cdf0e10cSrcweir 395cdf0e10cSrcweir const ::rtl::OUString* pFound = ::std::find_if( 396cdf0e10cSrcweir aAvailableServices.getConstArray(), 397cdf0e10cSrcweir aAvailableServices.getConstArray() + aAvailableServices.getLength(), 398cdf0e10cSrcweir StringCompare( _rService ) 399cdf0e10cSrcweir ); 400cdf0e10cSrcweir if ( pFound - aAvailableServices.getConstArray() < aAvailableServices.getLength() ) 401cdf0e10cSrcweir { 402cdf0e10cSrcweir bYesItIs = true; 403cdf0e10cSrcweir } 404cdf0e10cSrcweir } 405cdf0e10cSrcweir 406cdf0e10cSrcweir return bYesItIs; 407cdf0e10cSrcweir } 408cdf0e10cSrcweir 409cdf0e10cSrcweir //------------------------------------------------------------------------ isListCellRangeAllowed() const410cdf0e10cSrcweir bool CellBindingHelper::isListCellRangeAllowed( ) const 411cdf0e10cSrcweir { 412cdf0e10cSrcweir bool bAllow( false ); 413cdf0e10cSrcweir 414cdf0e10cSrcweir Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY ); 415cdf0e10cSrcweir if ( xSink.is() ) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_SHEET_CELLRANGE_LISTSOURCE ); 418cdf0e10cSrcweir } 419cdf0e10cSrcweir 420cdf0e10cSrcweir return bAllow; 421cdf0e10cSrcweir } 422cdf0e10cSrcweir 423cdf0e10cSrcweir //------------------------------------------------------------------------ isCellIntegerBindingAllowed() const424cdf0e10cSrcweir bool CellBindingHelper::isCellIntegerBindingAllowed( ) const 425cdf0e10cSrcweir { 426cdf0e10cSrcweir bool bAllow( true ); 427cdf0e10cSrcweir 428cdf0e10cSrcweir // first, we only offer this for controls which allow bindings in general 429cdf0e10cSrcweir Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY ); 430cdf0e10cSrcweir if ( !xBindable.is() ) 431cdf0e10cSrcweir bAllow = false; 432cdf0e10cSrcweir 433cdf0e10cSrcweir // then, we must live in a spreadsheet document which can provide the special 434cdf0e10cSrcweir // service needed for exchanging integer values 435cdf0e10cSrcweir if ( bAllow ) 436cdf0e10cSrcweir bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_SHEET_CELL_INT_BINDING ); 437cdf0e10cSrcweir 438cdf0e10cSrcweir // then, we only offer this for list boxes 439cdf0e10cSrcweir if ( bAllow ) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir try 442cdf0e10cSrcweir { 443cdf0e10cSrcweir sal_Int16 nClassId = FormComponentType::CONTROL; 444cdf0e10cSrcweir m_xControlModel->getPropertyValue( PROPERTY_CLASSID ) >>= nClassId; 445cdf0e10cSrcweir if ( FormComponentType::LISTBOX != nClassId ) 446cdf0e10cSrcweir bAllow = false; 447cdf0e10cSrcweir } 448cdf0e10cSrcweir catch( const Exception& ) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::isCellIntegerBindingAllowed: caught an exception!" ); 451cdf0e10cSrcweir // are there really control models which survive isCellBindingAllowed, but don't have a ClassId 452cdf0e10cSrcweir // property? 453cdf0e10cSrcweir bAllow = false; 454cdf0e10cSrcweir } 455cdf0e10cSrcweir } 456cdf0e10cSrcweir 457cdf0e10cSrcweir return bAllow; 458cdf0e10cSrcweir } 459cdf0e10cSrcweir 460cdf0e10cSrcweir //------------------------------------------------------------------------ isCellBindingAllowed() const461cdf0e10cSrcweir bool CellBindingHelper::isCellBindingAllowed( ) const 462cdf0e10cSrcweir { 463cdf0e10cSrcweir bool bAllow( false ); 464cdf0e10cSrcweir 465cdf0e10cSrcweir Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY ); 466cdf0e10cSrcweir if ( xBindable.is() ) 467cdf0e10cSrcweir { 468cdf0e10cSrcweir // the control can potentially be bound to an external value 469cdf0e10cSrcweir // Does it live within a Calc document, and is able to supply CellBindings? 470cdf0e10cSrcweir bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_SHEET_CELL_BINDING ); 471cdf0e10cSrcweir } 472cdf0e10cSrcweir 473cdf0e10cSrcweir // disallow for some types 474cdf0e10cSrcweir // TODO: shouldn't the XBindableValue supply a list of supported types, and we can distingusih 475cdf0e10cSrcweir // using this list? The current behavior below is somewhat hackish ... 476cdf0e10cSrcweir if ( bAllow ) 477cdf0e10cSrcweir { 478cdf0e10cSrcweir try 479cdf0e10cSrcweir { 480cdf0e10cSrcweir sal_Int16 nClassId = FormComponentType::CONTROL; 481cdf0e10cSrcweir m_xControlModel->getPropertyValue( PROPERTY_CLASSID ) >>= nClassId; 482cdf0e10cSrcweir if ( ( FormComponentType::DATEFIELD == nClassId ) || ( FormComponentType::TIMEFIELD == nClassId ) ) 483cdf0e10cSrcweir bAllow = false; 484cdf0e10cSrcweir } 485cdf0e10cSrcweir catch( const Exception& ) 486cdf0e10cSrcweir { 487cdf0e10cSrcweir OSL_ENSURE( sal_False, "CellBindingHelper::isCellBindingAllowed: caught an exception!" ); 488cdf0e10cSrcweir bAllow = false; 489cdf0e10cSrcweir } 490cdf0e10cSrcweir } 491cdf0e10cSrcweir return bAllow; 492cdf0e10cSrcweir } 493cdf0e10cSrcweir 494cdf0e10cSrcweir //------------------------------------------------------------------------ isCellBinding(const Reference<XValueBinding> & _rxBinding) const495cdf0e10cSrcweir bool CellBindingHelper::isCellBinding( const Reference< XValueBinding >& _rxBinding ) const 496cdf0e10cSrcweir { 497cdf0e10cSrcweir return doesComponentSupport( _rxBinding.get(), SERVICE_SHEET_CELL_BINDING ); 498cdf0e10cSrcweir } 499cdf0e10cSrcweir 500cdf0e10cSrcweir //------------------------------------------------------------------------ isCellIntegerBinding(const Reference<XValueBinding> & _rxBinding) const501cdf0e10cSrcweir bool CellBindingHelper::isCellIntegerBinding( const Reference< XValueBinding >& _rxBinding ) const 502cdf0e10cSrcweir { 503cdf0e10cSrcweir return doesComponentSupport( _rxBinding.get(), SERVICE_SHEET_CELL_INT_BINDING ); 504cdf0e10cSrcweir } 505cdf0e10cSrcweir 506cdf0e10cSrcweir //------------------------------------------------------------------------ isCellRangeListSource(const Reference<XListEntrySource> & _rxSource) const507cdf0e10cSrcweir bool CellBindingHelper::isCellRangeListSource( const Reference< XListEntrySource >& _rxSource ) const 508cdf0e10cSrcweir { 509cdf0e10cSrcweir return doesComponentSupport( _rxSource.get(), SERVICE_SHEET_CELLRANGE_LISTSOURCE ); 510cdf0e10cSrcweir } 511cdf0e10cSrcweir 512cdf0e10cSrcweir //------------------------------------------------------------------------ doesComponentSupport(const Reference<XInterface> & _rxComponent,const::rtl::OUString & _rService) const513cdf0e10cSrcweir bool CellBindingHelper::doesComponentSupport( const Reference< XInterface >& _rxComponent, const ::rtl::OUString& _rService ) const 514cdf0e10cSrcweir { 515cdf0e10cSrcweir bool bDoes = false; 516cdf0e10cSrcweir Reference< XServiceInfo > xSI( _rxComponent, UNO_QUERY ); 517cdf0e10cSrcweir bDoes = xSI.is() && xSI->supportsService( _rService ); 518cdf0e10cSrcweir return bDoes; 519cdf0e10cSrcweir } 520cdf0e10cSrcweir 521cdf0e10cSrcweir //------------------------------------------------------------------------ getCurrentBinding() const522cdf0e10cSrcweir Reference< XValueBinding > CellBindingHelper::getCurrentBinding( ) const 523cdf0e10cSrcweir { 524cdf0e10cSrcweir Reference< XValueBinding > xBinding; 525cdf0e10cSrcweir Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY ); 526cdf0e10cSrcweir if ( xBindable.is() ) 527cdf0e10cSrcweir xBinding = xBindable->getValueBinding(); 528cdf0e10cSrcweir return xBinding; 529cdf0e10cSrcweir } 530cdf0e10cSrcweir 531cdf0e10cSrcweir //------------------------------------------------------------------------ getCurrentListSource() const532cdf0e10cSrcweir Reference< XListEntrySource > CellBindingHelper::getCurrentListSource( ) const 533cdf0e10cSrcweir { 534cdf0e10cSrcweir Reference< XListEntrySource > xSource; 535cdf0e10cSrcweir Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY ); 536cdf0e10cSrcweir if ( xSink.is() ) 537cdf0e10cSrcweir xSource = xSink->getListEntrySource(); 538cdf0e10cSrcweir return xSource; 539cdf0e10cSrcweir } 540cdf0e10cSrcweir 541cdf0e10cSrcweir //------------------------------------------------------------------------ setBinding(const Reference<XValueBinding> & _rxBinding)542cdf0e10cSrcweir void CellBindingHelper::setBinding( const Reference< XValueBinding >& _rxBinding ) 543cdf0e10cSrcweir { 544cdf0e10cSrcweir Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY ); 545cdf0e10cSrcweir OSL_PRECOND( xBindable.is(), "CellBindingHelper::setBinding: the object is not bindable!" ); 546cdf0e10cSrcweir if ( xBindable.is() ) 547cdf0e10cSrcweir xBindable->setValueBinding( _rxBinding ); 548cdf0e10cSrcweir } 549cdf0e10cSrcweir 550cdf0e10cSrcweir //------------------------------------------------------------------------ setListSource(const Reference<XListEntrySource> & _rxSource)551cdf0e10cSrcweir void CellBindingHelper::setListSource( const Reference< XListEntrySource >& _rxSource ) 552cdf0e10cSrcweir { 553cdf0e10cSrcweir Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY ); 554cdf0e10cSrcweir OSL_PRECOND( xSink.is(), "CellBindingHelper::setListSource: the object is no list entry sink!" ); 555cdf0e10cSrcweir if ( xSink.is() ) 556cdf0e10cSrcweir xSink->setListEntrySource( _rxSource ); 557cdf0e10cSrcweir } 558cdf0e10cSrcweir 559cdf0e10cSrcweir //............................................................................ 560cdf0e10cSrcweir } // namespace pcr 561cdf0e10cSrcweir //............................................................................ 562