1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b3f79822SAndrew Rist  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b3f79822SAndrew Rist  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19*b3f79822SAndrew Rist  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir #include "celllistsource.hxx"
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir #include <com/sun/star/text/XTextRange.hpp>
29cdf0e10cSrcweir #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
30cdf0e10cSrcweir #include <com/sun/star/util/XModifyBroadcaster.hpp>
31cdf0e10cSrcweir #include <com/sun/star/container/XIndexAccess.hpp>
32cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
33cdf0e10cSrcweir #include <com/sun/star/beans/NamedValue.hpp>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir //.........................................................................
36cdf0e10cSrcweir namespace calc
37cdf0e10cSrcweir {
38cdf0e10cSrcweir //.........................................................................
39cdf0e10cSrcweir 
40cdf0e10cSrcweir #define PROP_HANDLE_RANGE_ADDRESS  1
41cdf0e10cSrcweir 
42cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
43cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
44cdf0e10cSrcweir     using namespace ::com::sun::star::table;
45cdf0e10cSrcweir     using namespace ::com::sun::star::text;
46cdf0e10cSrcweir     using namespace ::com::sun::star::sheet;
47cdf0e10cSrcweir     using namespace ::com::sun::star::container;
48cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
49cdf0e10cSrcweir     using namespace ::com::sun::star::util;
50cdf0e10cSrcweir     using namespace ::com::sun::star::form::binding;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir     //=====================================================================
53cdf0e10cSrcweir     //= OCellListSource
54cdf0e10cSrcweir     //=====================================================================
DBG_NAME(OCellListSource) const55cdf0e10cSrcweir     DBG_NAME( OCellListSource )
56cdf0e10cSrcweir     //---------------------------------------------------------------------
57cdf0e10cSrcweir #ifdef DBG_UTIL
58cdf0e10cSrcweir     const char* OCellListSource::checkConsistency_static( const void* _pThis )
59cdf0e10cSrcweir     {
60cdf0e10cSrcweir         return static_cast< const OCellListSource* >( _pThis )->checkConsistency( );
61cdf0e10cSrcweir     }
62cdf0e10cSrcweir 
checkConsistency() const63cdf0e10cSrcweir     const char* OCellListSource::checkConsistency( ) const
64cdf0e10cSrcweir     {
65cdf0e10cSrcweir         const char* pAssertion = NULL;
66cdf0e10cSrcweir 
67cdf0e10cSrcweir         // TODO: place any checks here to ensure consistency of this instance
68cdf0e10cSrcweir 
69cdf0e10cSrcweir         return pAssertion;
70cdf0e10cSrcweir     }
71cdf0e10cSrcweir #endif
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     //---------------------------------------------------------------------
OCellListSource(const Reference<XSpreadsheetDocument> & _rxDocument)74cdf0e10cSrcweir     OCellListSource::OCellListSource( const Reference< XSpreadsheetDocument >& _rxDocument )
75cdf0e10cSrcweir         :OCellListSource_Base( m_aMutex )
76cdf0e10cSrcweir         ,OCellListSource_PBase( OCellListSource_Base::rBHelper )
77cdf0e10cSrcweir         ,m_xDocument( _rxDocument )
78cdf0e10cSrcweir         ,m_aListEntryListeners( m_aMutex )
79cdf0e10cSrcweir         ,m_bInitialized( sal_False )
80cdf0e10cSrcweir     {
81cdf0e10cSrcweir         DBG_CTOR( OCellListSource, checkConsistency_static );
82cdf0e10cSrcweir 
83cdf0e10cSrcweir         OSL_PRECOND( m_xDocument.is(), "OCellListSource::OCellListSource: invalid document!" );
84cdf0e10cSrcweir 
85cdf0e10cSrcweir         // register our property at the base class
86cdf0e10cSrcweir         CellRangeAddress aInitialPropValue;
87cdf0e10cSrcweir 	    registerPropertyNoMember(
88cdf0e10cSrcweir             ::rtl::OUString::createFromAscii( "CellRange" ),
89cdf0e10cSrcweir             PROP_HANDLE_RANGE_ADDRESS,
90cdf0e10cSrcweir             PropertyAttribute::BOUND | PropertyAttribute::READONLY,
91cdf0e10cSrcweir             ::getCppuType( &aInitialPropValue ),
92cdf0e10cSrcweir             &aInitialPropValue
93cdf0e10cSrcweir         );
94cdf0e10cSrcweir     }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir     //---------------------------------------------------------------------
~OCellListSource()97cdf0e10cSrcweir     OCellListSource::~OCellListSource( )
98cdf0e10cSrcweir     {
99cdf0e10cSrcweir         if ( !OCellListSource_Base::rBHelper.bDisposed )
100cdf0e10cSrcweir         {
101cdf0e10cSrcweir             acquire();  // prevent duplicate dtor
102cdf0e10cSrcweir             dispose();
103cdf0e10cSrcweir         }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir         DBG_DTOR( OCellListSource, checkConsistency_static );
106cdf0e10cSrcweir     }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     //--------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(OCellListSource,OCellListSource_Base,OCellListSource_PBase)109cdf0e10cSrcweir     IMPLEMENT_FORWARD_XINTERFACE2( OCellListSource, OCellListSource_Base, OCellListSource_PBase )
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     //--------------------------------------------------------------------
112cdf0e10cSrcweir     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OCellListSource, OCellListSource_Base, OCellListSource_PBase )
113cdf0e10cSrcweir 
114cdf0e10cSrcweir     //--------------------------------------------------------------------
115cdf0e10cSrcweir     void SAL_CALL OCellListSource::disposing()
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
118cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
119cdf0e10cSrcweir 
120cdf0e10cSrcweir         Reference<XModifyBroadcaster> xBroadcaster( m_xRange, UNO_QUERY );
121cdf0e10cSrcweir         if ( xBroadcaster.is() )
122cdf0e10cSrcweir         {
123cdf0e10cSrcweir             xBroadcaster->removeModifyListener( this );
124cdf0e10cSrcweir         }
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         EventObject aDisposeEvent( *this );
127cdf0e10cSrcweir         m_aListEntryListeners.disposeAndClear( aDisposeEvent );
128cdf0e10cSrcweir 
129cdf0e10cSrcweir //        OCellListSource_Base::disposing();
130cdf0e10cSrcweir         WeakAggComponentImplHelperBase::disposing();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         // TODO: clean up here whatever you need to clean up (e.g. revoking listeners etc.)
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir     //--------------------------------------------------------------------
getPropertySetInfo()136cdf0e10cSrcweir     Reference< XPropertySetInfo > SAL_CALL OCellListSource::getPropertySetInfo(  ) throw(RuntimeException)
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
139cdf0e10cSrcweir     	return createPropertySetInfo( getInfoHelper() ) ;
140cdf0e10cSrcweir     }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir     //--------------------------------------------------------------------
getInfoHelper()143cdf0e10cSrcweir     ::cppu::IPropertyArrayHelper& SAL_CALL OCellListSource::getInfoHelper()
144cdf0e10cSrcweir     {
145cdf0e10cSrcweir 	    return *OCellListSource_PABase::getArrayHelper();
146cdf0e10cSrcweir     }
147cdf0e10cSrcweir 
148cdf0e10cSrcweir     //--------------------------------------------------------------------
createArrayHelper() const149cdf0e10cSrcweir     ::cppu::IPropertyArrayHelper* OCellListSource::createArrayHelper( ) const
150cdf0e10cSrcweir     {
151cdf0e10cSrcweir 	    Sequence< Property > aProps;
152cdf0e10cSrcweir 	    describeProperties( aProps );
153cdf0e10cSrcweir 	    return new ::cppu::OPropertyArrayHelper(aProps);
154cdf0e10cSrcweir     }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     //--------------------------------------------------------------------
getFastPropertyValue(Any & _rValue,sal_Int32 _nHandle) const157cdf0e10cSrcweir 	void SAL_CALL OCellListSource::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const
158cdf0e10cSrcweir     {
159cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
160cdf0e10cSrcweir         DBG_ASSERT( _nHandle == PROP_HANDLE_RANGE_ADDRESS, "OCellListSource::getFastPropertyValue: invalid handle!" );
161cdf0e10cSrcweir             // we only have this one property ....
162cdf0e10cSrcweir         (void)_nHandle;     // avoid warning in product version
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         _rValue <<= getRangeAddress( );
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     //--------------------------------------------------------------------
checkDisposed() const168cdf0e10cSrcweir     void OCellListSource::checkDisposed( ) const SAL_THROW( ( DisposedException ) )
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         if ( OCellListSource_Base::rBHelper.bInDispose || OCellListSource_Base::rBHelper.bDisposed )
171cdf0e10cSrcweir             throw DisposedException();
172cdf0e10cSrcweir             // TODO: is it worth having an error message here?
173cdf0e10cSrcweir     }
174cdf0e10cSrcweir 
175cdf0e10cSrcweir     //--------------------------------------------------------------------
checkInitialized()176cdf0e10cSrcweir     void OCellListSource::checkInitialized() SAL_THROW( ( RuntimeException ) )
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         if ( !m_bInitialized )
179cdf0e10cSrcweir             throw RuntimeException();
180cdf0e10cSrcweir             // TODO: error message
181cdf0e10cSrcweir     }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     //--------------------------------------------------------------------
getImplementationName()184cdf0e10cSrcweir     ::rtl::OUString SAL_CALL OCellListSource::getImplementationName(  ) throw (RuntimeException)
185cdf0e10cSrcweir     {
186cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.sheet.OCellListSource" ) );
187cdf0e10cSrcweir     }
188cdf0e10cSrcweir 
189cdf0e10cSrcweir     //--------------------------------------------------------------------
supportsService(const::rtl::OUString & _rServiceName)190cdf0e10cSrcweir     sal_Bool SAL_CALL OCellListSource::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
191cdf0e10cSrcweir     {
192cdf0e10cSrcweir         Sequence< ::rtl::OUString > aSupportedServices( getSupportedServiceNames() );
193cdf0e10cSrcweir         const ::rtl::OUString* pLookup = aSupportedServices.getConstArray();
194cdf0e10cSrcweir         const ::rtl::OUString* pLookupEnd = aSupportedServices.getConstArray() + aSupportedServices.getLength();
195cdf0e10cSrcweir         while ( pLookup != pLookupEnd )
196cdf0e10cSrcweir             if ( *pLookup++ == _rServiceName )
197cdf0e10cSrcweir                 return sal_True;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir         return sal_False;
200cdf0e10cSrcweir     }
201cdf0e10cSrcweir 
202cdf0e10cSrcweir     //--------------------------------------------------------------------
getSupportedServiceNames()203cdf0e10cSrcweir     Sequence< ::rtl::OUString > SAL_CALL OCellListSource::getSupportedServiceNames(  ) throw (RuntimeException)
204cdf0e10cSrcweir     {
205cdf0e10cSrcweir         Sequence< ::rtl::OUString > aServices( 2 );
206cdf0e10cSrcweir         aServices[ 0 ] =  ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.table.CellRangeListSource" ) );
207cdf0e10cSrcweir         aServices[ 1 ] =  ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.form.binding.ListEntrySource" ) );
208cdf0e10cSrcweir         return aServices;
209cdf0e10cSrcweir     }
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     //--------------------------------------------------------------------
getRangeAddress() const212cdf0e10cSrcweir     CellRangeAddress OCellListSource::getRangeAddress( ) const
213cdf0e10cSrcweir     {
214cdf0e10cSrcweir         OSL_PRECOND( m_xRange.is(), "OCellListSource::getRangeAddress: invalid range!" );
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         CellRangeAddress aAddress;
217cdf0e10cSrcweir         Reference< XCellRangeAddressable > xRangeAddress( m_xRange, UNO_QUERY );
218cdf0e10cSrcweir         if ( xRangeAddress.is() )
219cdf0e10cSrcweir             aAddress = xRangeAddress->getRangeAddress( );
220cdf0e10cSrcweir         return aAddress;
221cdf0e10cSrcweir     }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir     //--------------------------------------------------------------------
getCellTextContent_noCheck(sal_Int32 _nRangeRelativeColumn,sal_Int32 _nRangeRelativeRow)224cdf0e10cSrcweir     ::rtl::OUString OCellListSource::getCellTextContent_noCheck( sal_Int32 _nRangeRelativeColumn, sal_Int32 _nRangeRelativeRow )
225cdf0e10cSrcweir     {
226cdf0e10cSrcweir         OSL_PRECOND( m_xRange.is(), "OCellListSource::getRangeAddress: invalid range!" );
227cdf0e10cSrcweir         Reference< XTextRange > xCellText;
228cdf0e10cSrcweir         if ( m_xRange.is() )
229cdf0e10cSrcweir             xCellText.set(xCellText.query( m_xRange->getCellByPosition( _nRangeRelativeColumn, _nRangeRelativeRow ) ));
230cdf0e10cSrcweir 
231cdf0e10cSrcweir         ::rtl::OUString sText;
232cdf0e10cSrcweir         if ( xCellText.is() )
233cdf0e10cSrcweir             sText = xCellText->getString();
234cdf0e10cSrcweir         return sText;
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir 
237cdf0e10cSrcweir     //--------------------------------------------------------------------
getListEntryCount()238cdf0e10cSrcweir     sal_Int32 SAL_CALL OCellListSource::getListEntryCount(  ) throw (RuntimeException)
239cdf0e10cSrcweir     {
240cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
241cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
242cdf0e10cSrcweir         checkDisposed();
243cdf0e10cSrcweir         checkInitialized();
244cdf0e10cSrcweir 
245cdf0e10cSrcweir         CellRangeAddress aAddress( getRangeAddress( ) );
246cdf0e10cSrcweir         return aAddress.EndRow - aAddress.StartRow + 1;
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     //--------------------------------------------------------------------
getListEntry(sal_Int32 _nPosition)250cdf0e10cSrcweir     ::rtl::OUString SAL_CALL OCellListSource::getListEntry( sal_Int32 _nPosition ) throw (IndexOutOfBoundsException, RuntimeException)
251cdf0e10cSrcweir     {
252cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
253cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
254cdf0e10cSrcweir         checkDisposed();
255cdf0e10cSrcweir         checkInitialized();
256cdf0e10cSrcweir 
257cdf0e10cSrcweir         if ( _nPosition >= getListEntryCount() )
258cdf0e10cSrcweir             throw IndexOutOfBoundsException();
259cdf0e10cSrcweir 
260cdf0e10cSrcweir         return getCellTextContent_noCheck( 0, _nPosition );
261cdf0e10cSrcweir     }
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     //--------------------------------------------------------------------
getAllListEntries()264cdf0e10cSrcweir     Sequence< ::rtl::OUString > SAL_CALL OCellListSource::getAllListEntries(  ) throw (RuntimeException)
265cdf0e10cSrcweir     {
266cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
267cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
268cdf0e10cSrcweir         checkDisposed();
269cdf0e10cSrcweir         checkInitialized();
270cdf0e10cSrcweir 
271cdf0e10cSrcweir         Sequence< ::rtl::OUString > aAllEntries( getListEntryCount() );
272cdf0e10cSrcweir         ::rtl::OUString* pAllEntries = aAllEntries.getArray();
273cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < aAllEntries.getLength(); ++i )
274cdf0e10cSrcweir         {
275cdf0e10cSrcweir             *pAllEntries++ = getCellTextContent_noCheck( 0, i );
276cdf0e10cSrcweir         }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir         return aAllEntries;
279cdf0e10cSrcweir     }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     //--------------------------------------------------------------------
addListEntryListener(const Reference<XListEntryListener> & _rxListener)282cdf0e10cSrcweir     void SAL_CALL OCellListSource::addListEntryListener( const Reference< XListEntryListener >& _rxListener ) throw (NullPointerException, RuntimeException)
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
285cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
286cdf0e10cSrcweir         checkDisposed();
287cdf0e10cSrcweir         checkInitialized();
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         if ( !_rxListener.is() )
290cdf0e10cSrcweir             throw NullPointerException();
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         m_aListEntryListeners.addInterface( _rxListener );
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir 
295cdf0e10cSrcweir     //--------------------------------------------------------------------
removeListEntryListener(const Reference<XListEntryListener> & _rxListener)296cdf0e10cSrcweir     void SAL_CALL OCellListSource::removeListEntryListener( const Reference< XListEntryListener >& _rxListener ) throw (NullPointerException, RuntimeException)
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         ::osl::MutexGuard aGuard( m_aMutex );
299cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
300cdf0e10cSrcweir         checkDisposed();
301cdf0e10cSrcweir         checkInitialized();
302cdf0e10cSrcweir 
303cdf0e10cSrcweir         if ( !_rxListener.is() )
304cdf0e10cSrcweir             throw NullPointerException();
305cdf0e10cSrcweir 
306cdf0e10cSrcweir         m_aListEntryListeners.removeInterface( _rxListener );
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     //--------------------------------------------------------------------
modified(const EventObject &)310cdf0e10cSrcweir     void SAL_CALL OCellListSource::modified( const EventObject& /* aEvent */ ) throw (RuntimeException)
311cdf0e10cSrcweir     {
312cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
313cdf0e10cSrcweir 
314cdf0e10cSrcweir         notifyModified();
315cdf0e10cSrcweir     }
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     //--------------------------------------------------------------------
notifyModified()318cdf0e10cSrcweir     void OCellListSource::notifyModified()
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         EventObject aEvent;
321cdf0e10cSrcweir         aEvent.Source.set(*this);
322cdf0e10cSrcweir 
323cdf0e10cSrcweir 		::cppu::OInterfaceIteratorHelper aIter( m_aListEntryListeners );
324cdf0e10cSrcweir 		while ( aIter.hasMoreElements() )
325cdf0e10cSrcweir         {
326cdf0e10cSrcweir             try
327cdf0e10cSrcweir             {
328cdf0e10cSrcweir     			static_cast< XListEntryListener* >( aIter.next() )->allEntriesChanged( aEvent );
329cdf0e10cSrcweir             }
330cdf0e10cSrcweir             catch( const RuntimeException& )
331cdf0e10cSrcweir             {
332cdf0e10cSrcweir                 // silent this
333cdf0e10cSrcweir             }
334cdf0e10cSrcweir             catch( const Exception& )
335cdf0e10cSrcweir             {
336cdf0e10cSrcweir                 DBG_ERROR( "OCellListSource::notifyModified: caught a (non-runtime) exception!" );
337cdf0e10cSrcweir             }
338cdf0e10cSrcweir         }
339cdf0e10cSrcweir 
340cdf0e10cSrcweir     }
341cdf0e10cSrcweir 
342cdf0e10cSrcweir     //--------------------------------------------------------------------
disposing(const EventObject & aEvent)343cdf0e10cSrcweir     void SAL_CALL OCellListSource::disposing( const EventObject& aEvent ) throw (RuntimeException)
344cdf0e10cSrcweir     {
345cdf0e10cSrcweir         DBG_CHKTHIS( OCellListSource, checkConsistency_static );
346cdf0e10cSrcweir 
347cdf0e10cSrcweir         Reference<XInterface> xRangeInt( m_xRange, UNO_QUERY );
348cdf0e10cSrcweir         if ( xRangeInt == aEvent.Source )
349cdf0e10cSrcweir         {
350cdf0e10cSrcweir             // release references to range object
351cdf0e10cSrcweir             m_xRange.clear();
352cdf0e10cSrcweir         }
353cdf0e10cSrcweir     }
354cdf0e10cSrcweir 
355cdf0e10cSrcweir     //--------------------------------------------------------------------
initialize(const Sequence<Any> & _rArguments)356cdf0e10cSrcweir     void SAL_CALL OCellListSource::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
357cdf0e10cSrcweir     {
358cdf0e10cSrcweir         if ( m_bInitialized )
359cdf0e10cSrcweir             throw Exception();
360cdf0e10cSrcweir             // TODO: error message
361cdf0e10cSrcweir 
362cdf0e10cSrcweir         // get the cell address
363cdf0e10cSrcweir         CellRangeAddress aRangeAddress;
364cdf0e10cSrcweir         sal_Bool bFoundAddress = sal_False;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         const Any* pLoop = _rArguments.getConstArray();
367cdf0e10cSrcweir         const Any* pLoopEnd = _rArguments.getConstArray() + _rArguments.getLength();
368cdf0e10cSrcweir         for ( ; ( pLoop != pLoopEnd ) && !bFoundAddress; ++pLoop )
369cdf0e10cSrcweir         {
370cdf0e10cSrcweir             NamedValue aValue;
371cdf0e10cSrcweir             if ( *pLoop >>= aValue )
372cdf0e10cSrcweir             {
373cdf0e10cSrcweir                 if ( aValue.Name.equalsAscii( "CellRange" ) )
374cdf0e10cSrcweir                 {
375cdf0e10cSrcweir                     if ( aValue.Value >>= aRangeAddress )
376cdf0e10cSrcweir                         bFoundAddress = sal_True;
377cdf0e10cSrcweir                 }
378cdf0e10cSrcweir             }
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir 
381cdf0e10cSrcweir         if ( !bFoundAddress )
382cdf0e10cSrcweir             // TODO: error message
383cdf0e10cSrcweir             throw Exception();
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         // determine the range we're bound to
386cdf0e10cSrcweir         try
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             if ( m_xDocument.is() )
389cdf0e10cSrcweir             {
390cdf0e10cSrcweir                 // first the sheets collection
391cdf0e10cSrcweir                 Reference< XIndexAccess > xSheets(m_xDocument->getSheets( ), UNO_QUERY);
392cdf0e10cSrcweir                 DBG_ASSERT( xSheets.is(), "OCellListSource::initialize: could not retrieve the sheets!" );
393cdf0e10cSrcweir 
394cdf0e10cSrcweir                 if ( xSheets.is() )
395cdf0e10cSrcweir                 {
396cdf0e10cSrcweir                     // the concrete sheet
397cdf0e10cSrcweir                     Reference< XCellRange > xSheet(xSheets->getByIndex( aRangeAddress.Sheet ), UNO_QUERY);
398cdf0e10cSrcweir                     DBG_ASSERT( xSheet.is(), "OCellListSource::initialize: NULL sheet, but no exception!" );
399cdf0e10cSrcweir 
400cdf0e10cSrcweir                     // the concrete cell
401cdf0e10cSrcweir                     if ( xSheet.is() )
402cdf0e10cSrcweir                     {
403cdf0e10cSrcweir                         m_xRange.set(xSheet->getCellRangeByPosition(
404cdf0e10cSrcweir                             aRangeAddress.StartColumn, aRangeAddress.StartRow,
405cdf0e10cSrcweir                             aRangeAddress.EndColumn, aRangeAddress.EndRow));
406cdf0e10cSrcweir                         DBG_ASSERT( Reference< XCellRangeAddressable >( m_xRange, UNO_QUERY ).is(), "OCellListSource::initialize: either NULL range, or cell without address access!" );
407cdf0e10cSrcweir                     }
408cdf0e10cSrcweir                 }
409cdf0e10cSrcweir             }
410cdf0e10cSrcweir         }
411cdf0e10cSrcweir         catch( const Exception& )
412cdf0e10cSrcweir         {
413cdf0e10cSrcweir             DBG_ERROR( "OCellListSource::initialize: caught an exception while retrieving the cell object!" );
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir 
417cdf0e10cSrcweir         if ( !m_xRange.is() )
418cdf0e10cSrcweir             throw Exception();
419cdf0e10cSrcweir             // TODO error message
420cdf0e10cSrcweir 
421cdf0e10cSrcweir         Reference<XModifyBroadcaster> xBroadcaster( m_xRange, UNO_QUERY );
422cdf0e10cSrcweir         if ( xBroadcaster.is() )
423cdf0e10cSrcweir         {
424cdf0e10cSrcweir             xBroadcaster->addModifyListener( this );
425cdf0e10cSrcweir         }
426cdf0e10cSrcweir 
427cdf0e10cSrcweir         // TODO: add as XEventListener to the cell range, so we get notified when it dies,
428cdf0e10cSrcweir         // and can dispose ourself then
429cdf0e10cSrcweir 
430cdf0e10cSrcweir         // TODO: somehow add as listener so we get notified when the address of the cell range changes
431cdf0e10cSrcweir         // We need to forward this as change in our CellRange property to our property change listeners
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         // TODO: somehow add as listener to the cells in the range, so that we get notified
434cdf0e10cSrcweir         // when their content changes. We need to forward this to our list entry listeners then
435cdf0e10cSrcweir 
436cdf0e10cSrcweir         // TODO: somehow add as listener so that we get notified of insertions and removals of rows in our
437cdf0e10cSrcweir         // range. In this case, we need to fire a change in our CellRange property, and additionally
438cdf0e10cSrcweir         // notify our XListEntryListeners
439cdf0e10cSrcweir 
440cdf0e10cSrcweir         m_bInitialized = sal_True;
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir //.........................................................................
444cdf0e10cSrcweir }   // namespace calc
445cdf0e10cSrcweir //.........................................................................
446