1*63bba73cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*63bba73cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*63bba73cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*63bba73cSAndrew Rist  * distributed with this work for additional information
6*63bba73cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*63bba73cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*63bba73cSAndrew Rist  * "License"); you may not use this file except in compliance
9*63bba73cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*63bba73cSAndrew Rist  *
11*63bba73cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*63bba73cSAndrew Rist  *
13*63bba73cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*63bba73cSAndrew Rist  * software distributed under the License is distributed on an
15*63bba73cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*63bba73cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*63bba73cSAndrew Rist  * specific language governing permissions and limitations
18*63bba73cSAndrew Rist  * under the License.
19*63bba73cSAndrew Rist  *
20*63bba73cSAndrew Rist  *************************************************************/
21*63bba73cSAndrew Rist 
22*63bba73cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_xmloff.hxx"
26cdf0e10cSrcweir #include "formcellbinding.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/XGridColumnFactory.hpp>
30cdf0e10cSrcweir #include <com/sun/star/frame/XModel.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 "strings.hxx"
41cdf0e10cSrcweir #include <osl/diagnose.h>
42cdf0e10cSrcweir #include <rtl/logfile.hxx>
43cdf0e10cSrcweir 
44cdf0e10cSrcweir #include <functional>
45cdf0e10cSrcweir #include <algorithm>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //............................................................................
48cdf0e10cSrcweir namespace xmloff
49cdf0e10cSrcweir {
50cdf0e10cSrcweir //............................................................................
51cdf0e10cSrcweir 
52cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
53cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
54cdf0e10cSrcweir     using namespace ::com::sun::star::frame;
55cdf0e10cSrcweir     using namespace ::com::sun::star::sheet;
56cdf0e10cSrcweir     using namespace ::com::sun::star::container;
57cdf0e10cSrcweir     using namespace ::com::sun::star::drawing;
58cdf0e10cSrcweir     using namespace ::com::sun::star::table;
59cdf0e10cSrcweir     using namespace ::com::sun::star::form;
60cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
61cdf0e10cSrcweir     using namespace ::com::sun::star::form::binding;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir namespace
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     using ::com::sun::star::uno::Reference;
66cdf0e10cSrcweir     using ::com::sun::star::uno::XInterface;
67cdf0e10cSrcweir     using ::com::sun::star::container::XChild;
68cdf0e10cSrcweir     using ::com::sun::star::frame::XModel;
69cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY;
70cdf0e10cSrcweir 
71cdf0e10cSrcweir 	//....................................................................
72cdf0e10cSrcweir     template< class TYPE >
getTypedModelNode(const Reference<XInterface> & _rxModelNode)73cdf0e10cSrcweir     Reference< TYPE > getTypedModelNode( const Reference< XInterface >& _rxModelNode )
74cdf0e10cSrcweir     {
75cdf0e10cSrcweir         Reference< TYPE > xTypedNode( _rxModelNode, UNO_QUERY );
76cdf0e10cSrcweir         if ( xTypedNode.is() )
77cdf0e10cSrcweir 	        return xTypedNode;
78cdf0e10cSrcweir         else
79cdf0e10cSrcweir         {
80cdf0e10cSrcweir 	        Reference< XChild > xChild( _rxModelNode, UNO_QUERY );
81cdf0e10cSrcweir 	        if ( xChild.is() )
82cdf0e10cSrcweir 		        return getTypedModelNode< TYPE >( xChild->getParent() );
83cdf0e10cSrcweir 	        else
84cdf0e10cSrcweir 		        return NULL;
85cdf0e10cSrcweir         }
86cdf0e10cSrcweir     }
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	//....................................................................
getDocument(const Reference<XInterface> & _rxModelNode)89cdf0e10cSrcweir     Reference< XModel > getDocument( const Reference< XInterface >& _rxModelNode )
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         return getTypedModelNode< XModel >( _rxModelNode );
92cdf0e10cSrcweir     }
93cdf0e10cSrcweir 
94cdf0e10cSrcweir     //....................................................................
95cdf0e10cSrcweir     struct StringCompare : public ::std::unary_function< ::rtl::OUString, bool >
96cdf0e10cSrcweir     {
97cdf0e10cSrcweir     private:
98cdf0e10cSrcweir         const ::rtl::OUString m_sReference;
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     public:
StringComparexmloff::__anon1ed97e980111::StringCompare101cdf0e10cSrcweir         StringCompare( const ::rtl::OUString& _rReference ) : m_sReference( _rReference ) { }
102cdf0e10cSrcweir 
operator ()xmloff::__anon1ed97e980111::StringCompare103cdf0e10cSrcweir         inline bool operator()( const ::rtl::OUString& _rCompare )
104cdf0e10cSrcweir         {
105cdf0e10cSrcweir             return ( _rCompare == m_sReference );
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir     };
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
110cdf0e10cSrcweir //========================================================================
111cdf0e10cSrcweir //= FormCellBindingHelper
112cdf0e10cSrcweir //========================================================================
113cdf0e10cSrcweir //------------------------------------------------------------------------
FormCellBindingHelper(const Reference<XPropertySet> & _rxControlModel,const Reference<XModel> & _rxDocument)114cdf0e10cSrcweir FormCellBindingHelper::FormCellBindingHelper( const Reference< XPropertySet >& _rxControlModel, const Reference< XModel >& _rxDocument )
115cdf0e10cSrcweir     :m_xControlModel( _rxControlModel )
116cdf0e10cSrcweir     ,m_xDocument( _rxDocument, UNO_QUERY )
117cdf0e10cSrcweir {
118cdf0e10cSrcweir     OSL_ENSURE( m_xControlModel.is(), "FormCellBindingHelper::FormCellBindingHelper: invalid control model!" );
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     if ( !m_xDocument.is() )
121cdf0e10cSrcweir         m_xDocument = m_xDocument.query( getDocument( m_xControlModel ) );
122cdf0e10cSrcweir     OSL_ENSURE( m_xDocument.is(), "FormCellBindingHelper::FormCellBindingHelper: Did not find the spreadsheet document!" );
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
125cdf0e10cSrcweir //------------------------------------------------------------------------
livesInSpreadsheetDocument(const Reference<XPropertySet> & _rxControlModel)126cdf0e10cSrcweir sal_Bool FormCellBindingHelper::livesInSpreadsheetDocument( const Reference< XPropertySet >& _rxControlModel )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir     Reference< XSpreadsheetDocument > xDocument( getDocument( _rxControlModel ), UNO_QUERY );
129cdf0e10cSrcweir     return xDocument.is();
130cdf0e10cSrcweir }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir //------------------------------------------------------------------------
convertStringAddress(const::rtl::OUString & _rAddressDescription,CellAddress & _rAddress,sal_Int16) const133cdf0e10cSrcweir bool FormCellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription, CellAddress& /* [out] */ _rAddress, sal_Int16 /*_nAssumeSheet*/ ) const
134cdf0e10cSrcweir {
135cdf0e10cSrcweir     Any aAddress;
136cdf0e10cSrcweir     return doConvertAddressRepresentations(
137cdf0e10cSrcweir                 PROPERTY_FILE_REPRESENTATION,
138cdf0e10cSrcweir                 makeAny( _rAddressDescription ),
139cdf0e10cSrcweir                 PROPERTY_ADDRESS,
140cdf0e10cSrcweir                 aAddress,
141cdf0e10cSrcweir                 false
142cdf0e10cSrcweir            )
143cdf0e10cSrcweir        &&  ( aAddress >>= _rAddress );
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir //------------------------------------------------------------------------
convertStringAddress(const::rtl::OUString & _rAddressDescription,CellRangeAddress & _rAddress) const147cdf0e10cSrcweir bool FormCellBindingHelper::convertStringAddress( const ::rtl::OUString& _rAddressDescription,
148cdf0e10cSrcweir                         CellRangeAddress& /* [out] */ _rAddress ) const
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     Any aAddress;
151cdf0e10cSrcweir     return doConvertAddressRepresentations(
152cdf0e10cSrcweir                 PROPERTY_FILE_REPRESENTATION,
153cdf0e10cSrcweir                 makeAny( _rAddressDescription ),
154cdf0e10cSrcweir                 PROPERTY_ADDRESS,
155cdf0e10cSrcweir                 aAddress,
156cdf0e10cSrcweir                 true
157cdf0e10cSrcweir            )
158cdf0e10cSrcweir        &&  ( aAddress >>= _rAddress );
159cdf0e10cSrcweir }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir //------------------------------------------------------------------------
createCellBindingFromStringAddress(const::rtl::OUString & _rAddress,bool _bUseIntegerBinding) const162cdf0e10cSrcweir Reference< XValueBinding > FormCellBindingHelper::createCellBindingFromStringAddress( const ::rtl::OUString& _rAddress, bool _bUseIntegerBinding ) const
163cdf0e10cSrcweir {
164cdf0e10cSrcweir     Reference< XValueBinding > xBinding;
165cdf0e10cSrcweir     if ( !m_xDocument.is() )
166cdf0e10cSrcweir         // very bad ...
167cdf0e10cSrcweir         return xBinding;
168cdf0e10cSrcweir 
169cdf0e10cSrcweir     // get the UNO representation of the address
170cdf0e10cSrcweir     CellAddress aAddress;
171cdf0e10cSrcweir     if ( !_rAddress.getLength() || !convertStringAddress( _rAddress, aAddress ) )
172cdf0e10cSrcweir         return xBinding;
173cdf0e10cSrcweir 
174cdf0e10cSrcweir     xBinding = xBinding.query( createDocumentDependentInstance(
175cdf0e10cSrcweir         _bUseIntegerBinding ? SERVICE_LISTINDEXCELLBINDING : SERVICE_CELLVALUEBINDING,
176cdf0e10cSrcweir         PROPERTY_BOUND_CELL,
177cdf0e10cSrcweir         makeAny( aAddress )
178cdf0e10cSrcweir     ) );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     return xBinding;
181cdf0e10cSrcweir }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir //------------------------------------------------------------------------
createCellListSourceFromStringAddress(const::rtl::OUString & _rAddress) const184cdf0e10cSrcweir Reference< XListEntrySource > FormCellBindingHelper::createCellListSourceFromStringAddress( const ::rtl::OUString& _rAddress ) const
185cdf0e10cSrcweir {
186cdf0e10cSrcweir     Reference< XListEntrySource > xSource;
187cdf0e10cSrcweir 
188cdf0e10cSrcweir     CellRangeAddress aRangeAddress;
189cdf0e10cSrcweir     if ( !convertStringAddress( _rAddress, aRangeAddress ) )
190cdf0e10cSrcweir         return xSource;
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     // create a range object for this address
193cdf0e10cSrcweir     xSource = xSource.query( createDocumentDependentInstance(
194cdf0e10cSrcweir         SERVICE_CELLRANGELISTSOURCE,
195cdf0e10cSrcweir         PROPERTY_LIST_CELL_RANGE,
196cdf0e10cSrcweir         makeAny( aRangeAddress )
197cdf0e10cSrcweir     ) );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     return xSource;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir //------------------------------------------------------------------------
getStringAddressFromCellBinding(const Reference<XValueBinding> & _rxBinding) const203cdf0e10cSrcweir ::rtl::OUString FormCellBindingHelper::getStringAddressFromCellBinding( const Reference< XValueBinding >& _rxBinding ) const
204cdf0e10cSrcweir {
205cdf0e10cSrcweir     OSL_PRECOND( !_rxBinding.is() || isCellBinding( _rxBinding ), "FormCellBindingHelper::getStringAddressFromCellBinding: this is no cell binding!" );
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     ::rtl::OUString sAddress;
208cdf0e10cSrcweir     try
209cdf0e10cSrcweir     {
210cdf0e10cSrcweir         Reference< XPropertySet > xBindingProps( _rxBinding, UNO_QUERY );
211cdf0e10cSrcweir         OSL_ENSURE( xBindingProps.is() || !_rxBinding.is(), "FormCellBindingHelper::getStringAddressFromCellBinding: no property set for the binding!" );
212cdf0e10cSrcweir         if ( xBindingProps.is() )
213cdf0e10cSrcweir         {
214cdf0e10cSrcweir             CellAddress aAddress;
215cdf0e10cSrcweir             xBindingProps->getPropertyValue( PROPERTY_BOUND_CELL ) >>= aAddress;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir             Any aStringAddress;
218cdf0e10cSrcweir             doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aAddress ),
219cdf0e10cSrcweir                 PROPERTY_FILE_REPRESENTATION, aStringAddress, false );
220cdf0e10cSrcweir 
221cdf0e10cSrcweir             aStringAddress >>= sAddress;
222cdf0e10cSrcweir         }
223cdf0e10cSrcweir     }
224cdf0e10cSrcweir     catch( const Exception& )
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         OSL_ENSURE( sal_False, "FormCellBindingHelper::getStringAddressFromCellBinding: caught an exception!" );
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir 
229cdf0e10cSrcweir     return sAddress;
230cdf0e10cSrcweir }
231cdf0e10cSrcweir 
232cdf0e10cSrcweir //------------------------------------------------------------------------
getStringAddressFromCellListSource(const Reference<XListEntrySource> & _rxSource) const233cdf0e10cSrcweir ::rtl::OUString FormCellBindingHelper::getStringAddressFromCellListSource( const Reference< XListEntrySource >& _rxSource ) const
234cdf0e10cSrcweir {
235cdf0e10cSrcweir     OSL_PRECOND( !_rxSource.is() || isCellRangeListSource( _rxSource ), "FormCellBindingHelper::getStringAddressFromCellListSource: this is no cell list source!" );
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     ::rtl::OUString sAddress;
238cdf0e10cSrcweir     try
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         Reference< XPropertySet > xSourceProps( _rxSource, UNO_QUERY );
241cdf0e10cSrcweir         OSL_ENSURE( xSourceProps.is() || !_rxSource.is(), "FormCellBindingHelper::getStringAddressFromCellListSource: no property set for the list source!" );
242cdf0e10cSrcweir         if ( xSourceProps.is() )
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir             CellRangeAddress aRangeAddress;
245cdf0e10cSrcweir             xSourceProps->getPropertyValue( PROPERTY_LIST_CELL_RANGE ) >>= aRangeAddress;
246cdf0e10cSrcweir 
247cdf0e10cSrcweir             Any aStringAddress;
248cdf0e10cSrcweir             doConvertAddressRepresentations( PROPERTY_ADDRESS, makeAny( aRangeAddress ),
249cdf0e10cSrcweir                 PROPERTY_FILE_REPRESENTATION, aStringAddress, true );
250cdf0e10cSrcweir             aStringAddress >>= sAddress;
251cdf0e10cSrcweir         }
252cdf0e10cSrcweir     }
253cdf0e10cSrcweir     catch( const Exception& )
254cdf0e10cSrcweir     {
255cdf0e10cSrcweir         OSL_ENSURE( sal_False, "FormCellBindingHelper::getStringAddressFromCellListSource: caught an exception!" );
256cdf0e10cSrcweir     }
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     return sAddress;
259cdf0e10cSrcweir }
260cdf0e10cSrcweir 
261cdf0e10cSrcweir //------------------------------------------------------------------------
isSpreadsheetDocumentWhichSupplies(const Reference<XSpreadsheetDocument> & _rxDocument,const::rtl::OUString & _rService)262cdf0e10cSrcweir bool FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies( const Reference< XSpreadsheetDocument >& _rxDocument, const ::rtl::OUString& _rService ) SAL_THROW(())
263cdf0e10cSrcweir {
264cdf0e10cSrcweir     bool bYesItIs = false;
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     try
267cdf0e10cSrcweir     {
268cdf0e10cSrcweir         Reference< XServiceInfo > xSI( _rxDocument, UNO_QUERY );
269cdf0e10cSrcweir         if ( xSI.is() && xSI->supportsService( SERVICE_SPREADSHEET_DOCUMENT ) )
270cdf0e10cSrcweir         {
271cdf0e10cSrcweir             Reference< XMultiServiceFactory > xDocumentFactory( _rxDocument, UNO_QUERY );
272cdf0e10cSrcweir             OSL_ENSURE( xDocumentFactory.is(), "FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies: spreadsheet document, but no factory?" );
273cdf0e10cSrcweir 
274cdf0e10cSrcweir             Sequence< ::rtl::OUString > aAvailableServices;
275cdf0e10cSrcweir             if ( xDocumentFactory.is() )
276cdf0e10cSrcweir                 aAvailableServices = xDocumentFactory->getAvailableServiceNames( );
277cdf0e10cSrcweir 
278cdf0e10cSrcweir             const ::rtl::OUString* pFound = ::std::find_if(
279cdf0e10cSrcweir                 aAvailableServices.getConstArray(),
280cdf0e10cSrcweir                 aAvailableServices.getConstArray() + aAvailableServices.getLength(),
281cdf0e10cSrcweir                 StringCompare( _rService )
282cdf0e10cSrcweir             );
283cdf0e10cSrcweir             if ( pFound - aAvailableServices.getConstArray() < aAvailableServices.getLength() )
284cdf0e10cSrcweir             {
285cdf0e10cSrcweir                 bYesItIs = true;
286cdf0e10cSrcweir             }
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir     }
289cdf0e10cSrcweir     catch( const Exception& )
290cdf0e10cSrcweir     {
291cdf0e10cSrcweir         OSL_ENSURE( sal_False, "FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies: caught an exception!" );
292cdf0e10cSrcweir     }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir     return bYesItIs;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir //------------------------------------------------------------------------
isSpreadsheetDocumentWhichSupplies(const::rtl::OUString & _rService) const298cdf0e10cSrcweir bool FormCellBindingHelper::isSpreadsheetDocumentWhichSupplies( const ::rtl::OUString& _rService ) const SAL_THROW(())
299cdf0e10cSrcweir {
300cdf0e10cSrcweir     return isSpreadsheetDocumentWhichSupplies( m_xDocument, _rService );
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir //------------------------------------------------------------------------
isListCellRangeAllowed(const Reference<XModel> & _rxDocument)304cdf0e10cSrcweir bool FormCellBindingHelper::isListCellRangeAllowed( const Reference< XModel >& _rxDocument )
305cdf0e10cSrcweir {
306cdf0e10cSrcweir     return isSpreadsheetDocumentWhichSupplies(
307cdf0e10cSrcweir         Reference< XSpreadsheetDocument >( _rxDocument, UNO_QUERY ),
308cdf0e10cSrcweir         SERVICE_CELLRANGELISTSOURCE
309cdf0e10cSrcweir     );
310cdf0e10cSrcweir }
311cdf0e10cSrcweir 
312cdf0e10cSrcweir //------------------------------------------------------------------------
isListCellRangeAllowed() const313cdf0e10cSrcweir bool FormCellBindingHelper::isListCellRangeAllowed( ) const
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     bool bAllow( false );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
318cdf0e10cSrcweir     if ( xSink.is() )
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_CELLRANGELISTSOURCE );
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     return bAllow;
324cdf0e10cSrcweir }
325cdf0e10cSrcweir 
326cdf0e10cSrcweir //------------------------------------------------------------------------
isCellBindingAllowed() const327cdf0e10cSrcweir bool FormCellBindingHelper::isCellBindingAllowed( ) const
328cdf0e10cSrcweir {
329cdf0e10cSrcweir     bool bAllow( false );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir     Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
332cdf0e10cSrcweir     if ( xBindable.is() )
333cdf0e10cSrcweir     {
334cdf0e10cSrcweir         // the control can potentially be bound to an external value
335cdf0e10cSrcweir         // Does it live within a Calc document, and is able to supply CellBindings?
336cdf0e10cSrcweir         bAllow = isSpreadsheetDocumentWhichSupplies( SERVICE_CELLVALUEBINDING );
337cdf0e10cSrcweir     }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     return bAllow;
340cdf0e10cSrcweir }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir //------------------------------------------------------------------------
isCellBindingAllowed(const Reference<XModel> & _rxDocument)343cdf0e10cSrcweir bool FormCellBindingHelper::isCellBindingAllowed( const Reference< XModel >& _rxDocument )
344cdf0e10cSrcweir {
345cdf0e10cSrcweir     return isSpreadsheetDocumentWhichSupplies(
346cdf0e10cSrcweir         Reference< XSpreadsheetDocument >( _rxDocument, UNO_QUERY ),
347cdf0e10cSrcweir         SERVICE_CELLVALUEBINDING
348cdf0e10cSrcweir     );
349cdf0e10cSrcweir }
350cdf0e10cSrcweir 
351cdf0e10cSrcweir //------------------------------------------------------------------------
isCellBinding(const Reference<XValueBinding> & _rxBinding) const352cdf0e10cSrcweir bool FormCellBindingHelper::isCellBinding( const Reference< XValueBinding >& _rxBinding ) const
353cdf0e10cSrcweir {
354cdf0e10cSrcweir     return doesComponentSupport( _rxBinding.get(), SERVICE_CELLVALUEBINDING );
355cdf0e10cSrcweir }
356cdf0e10cSrcweir 
357cdf0e10cSrcweir //------------------------------------------------------------------------
isCellIntegerBinding(const Reference<XValueBinding> & _rxBinding) const358cdf0e10cSrcweir bool FormCellBindingHelper::isCellIntegerBinding( const Reference< XValueBinding >& _rxBinding ) const
359cdf0e10cSrcweir {
360cdf0e10cSrcweir     return doesComponentSupport( _rxBinding.get(), SERVICE_LISTINDEXCELLBINDING );
361cdf0e10cSrcweir }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir //------------------------------------------------------------------------
isCellRangeListSource(const Reference<XListEntrySource> & _rxSource) const364cdf0e10cSrcweir bool FormCellBindingHelper::isCellRangeListSource( const Reference< XListEntrySource >& _rxSource ) const
365cdf0e10cSrcweir {
366cdf0e10cSrcweir     return doesComponentSupport( _rxSource.get(), SERVICE_CELLRANGELISTSOURCE );
367cdf0e10cSrcweir }
368cdf0e10cSrcweir 
369cdf0e10cSrcweir //------------------------------------------------------------------------
doesComponentSupport(const Reference<XInterface> & _rxComponent,const::rtl::OUString & _rService) const370cdf0e10cSrcweir bool FormCellBindingHelper::doesComponentSupport( const Reference< XInterface >& _rxComponent, const ::rtl::OUString& _rService ) const
371cdf0e10cSrcweir {
372cdf0e10cSrcweir     bool bDoes = false;
373cdf0e10cSrcweir     Reference< XServiceInfo > xSI( _rxComponent, UNO_QUERY );
374cdf0e10cSrcweir     bDoes = xSI.is() && xSI->supportsService( _rService );
375cdf0e10cSrcweir     return bDoes;
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir //------------------------------------------------------------------------
getCurrentBinding() const379cdf0e10cSrcweir Reference< XValueBinding > FormCellBindingHelper::getCurrentBinding( ) const
380cdf0e10cSrcweir {
381cdf0e10cSrcweir     Reference< XValueBinding > xBinding;
382cdf0e10cSrcweir     Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
383cdf0e10cSrcweir     if ( xBindable.is() )
384cdf0e10cSrcweir         xBinding = xBindable->getValueBinding();
385cdf0e10cSrcweir     return xBinding;
386cdf0e10cSrcweir }
387cdf0e10cSrcweir 
388cdf0e10cSrcweir //------------------------------------------------------------------------
getCurrentListSource() const389cdf0e10cSrcweir Reference< XListEntrySource > FormCellBindingHelper::getCurrentListSource( ) const
390cdf0e10cSrcweir {
391cdf0e10cSrcweir     Reference< XListEntrySource > xSource;
392cdf0e10cSrcweir     Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
393cdf0e10cSrcweir     if ( xSink.is() )
394cdf0e10cSrcweir         xSource = xSink->getListEntrySource();
395cdf0e10cSrcweir     return xSource;
396cdf0e10cSrcweir }
397cdf0e10cSrcweir 
398cdf0e10cSrcweir //------------------------------------------------------------------------
setBinding(const Reference<XValueBinding> & _rxBinding)399cdf0e10cSrcweir void FormCellBindingHelper::setBinding( const Reference< XValueBinding >& _rxBinding )
400cdf0e10cSrcweir {
401cdf0e10cSrcweir     Reference< XBindableValue > xBindable( m_xControlModel, UNO_QUERY );
402cdf0e10cSrcweir     OSL_PRECOND( xBindable.is(), "FormCellBindingHelper::setBinding: the object is not bindable!" );
403cdf0e10cSrcweir     if ( xBindable.is() )
404cdf0e10cSrcweir         xBindable->setValueBinding( _rxBinding );
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir //------------------------------------------------------------------------
setListSource(const Reference<XListEntrySource> & _rxSource)408cdf0e10cSrcweir void FormCellBindingHelper::setListSource( const Reference< XListEntrySource >& _rxSource )
409cdf0e10cSrcweir {
410cdf0e10cSrcweir     Reference< XListEntrySink > xSink( m_xControlModel, UNO_QUERY );
411cdf0e10cSrcweir     OSL_PRECOND( xSink.is(), "FormCellBindingHelper::setListSource: the object is no list entry sink!" );
412cdf0e10cSrcweir     if ( xSink.is() )
413cdf0e10cSrcweir         xSink->setListEntrySource( _rxSource );
414cdf0e10cSrcweir }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir //------------------------------------------------------------------------
createDocumentDependentInstance(const::rtl::OUString & _rService,const::rtl::OUString & _rArgumentName,const Any & _rArgumentValue) const417cdf0e10cSrcweir Reference< XInterface > FormCellBindingHelper::createDocumentDependentInstance( const ::rtl::OUString& _rService, const ::rtl::OUString& _rArgumentName,
418cdf0e10cSrcweir     const Any& _rArgumentValue ) const
419cdf0e10cSrcweir {
420cdf0e10cSrcweir     Reference< XInterface > xReturn;
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     Reference< XMultiServiceFactory > xDocumentFactory( m_xDocument, UNO_QUERY );
423cdf0e10cSrcweir     OSL_ENSURE( xDocumentFactory.is(), "FormCellBindingHelper::createDocumentDependentInstance: no document service factory!" );
424cdf0e10cSrcweir     if ( xDocumentFactory.is() )
425cdf0e10cSrcweir     {
426cdf0e10cSrcweir         try
427cdf0e10cSrcweir         {
428cdf0e10cSrcweir             if ( _rArgumentName.getLength() )
429cdf0e10cSrcweir             {
430cdf0e10cSrcweir                 NamedValue aArg;
431cdf0e10cSrcweir                 aArg.Name = _rArgumentName;
432cdf0e10cSrcweir                 aArg.Value = _rArgumentValue;
433cdf0e10cSrcweir 
434cdf0e10cSrcweir                 Sequence< Any > aArgs( 1 );
435cdf0e10cSrcweir                 aArgs[ 0 ] <<= aArg;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir                 xReturn = xDocumentFactory->createInstanceWithArguments( _rService, aArgs );
438cdf0e10cSrcweir             }
439cdf0e10cSrcweir             else
440cdf0e10cSrcweir             {
441cdf0e10cSrcweir                 xReturn = xDocumentFactory->createInstance( _rService );
442cdf0e10cSrcweir             }
443cdf0e10cSrcweir         }
444cdf0e10cSrcweir         catch ( const Exception& )
445cdf0e10cSrcweir         {
446cdf0e10cSrcweir             OSL_ENSURE( sal_False, "FormCellBindingHelper::createDocumentDependentInstance: could not create the binding at the document!" );
447cdf0e10cSrcweir         }
448cdf0e10cSrcweir     }
449cdf0e10cSrcweir     return xReturn;
450cdf0e10cSrcweir }
451cdf0e10cSrcweir 
452cdf0e10cSrcweir //------------------------------------------------------------------------
doConvertAddressRepresentations(const::rtl::OUString & _rInputProperty,const Any & _rInputValue,const::rtl::OUString & _rOutputProperty,Any & _rOutputValue,bool _bIsRange) const453cdf0e10cSrcweir bool FormCellBindingHelper::doConvertAddressRepresentations( const ::rtl::OUString& _rInputProperty, const Any& _rInputValue,
454cdf0e10cSrcweir     const ::rtl::OUString& _rOutputProperty, Any& _rOutputValue, bool _bIsRange ) const SAL_THROW(())
455cdf0e10cSrcweir {
456cdf0e10cSrcweir     bool bSuccess = false;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir     Reference< XPropertySet > xConverter(
459cdf0e10cSrcweir         createDocumentDependentInstance(
460cdf0e10cSrcweir             _bIsRange ? SERVICE_RANGEADDRESS_CONVERSION : SERVICE_ADDRESS_CONVERSION,
461cdf0e10cSrcweir             ::rtl::OUString(),
462cdf0e10cSrcweir             Any()
463cdf0e10cSrcweir         ),
464cdf0e10cSrcweir         UNO_QUERY
465cdf0e10cSrcweir     );
466cdf0e10cSrcweir     OSL_ENSURE( xConverter.is(), "FormCellBindingHelper::doConvertAddressRepresentations: could not get a converter service!" );
467cdf0e10cSrcweir     if ( xConverter.is() )
468cdf0e10cSrcweir     {
469cdf0e10cSrcweir         try
470cdf0e10cSrcweir         {
471cdf0e10cSrcweir             xConverter->setPropertyValue( _rInputProperty, _rInputValue );
472cdf0e10cSrcweir             _rOutputValue = xConverter->getPropertyValue( _rOutputProperty );
473cdf0e10cSrcweir             bSuccess = true;
474cdf0e10cSrcweir         }
475cdf0e10cSrcweir         catch( const Exception& )
476cdf0e10cSrcweir         {
477cdf0e10cSrcweir         	OSL_ENSURE( sal_False, "FormCellBindingHelper::doConvertAddressRepresentations: caught an exception!" );
478cdf0e10cSrcweir         }
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir     return bSuccess;
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir //............................................................................
485cdf0e10cSrcweir }   // namespace xmloff
486cdf0e10cSrcweir //............................................................................
487