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