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