1*b0724fc6SAndrew Rist /**************************************************************
2*b0724fc6SAndrew Rist  *
3*b0724fc6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b0724fc6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b0724fc6SAndrew Rist  * distributed with this work for additional information
6*b0724fc6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b0724fc6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b0724fc6SAndrew Rist  * "License"); you may not use this file except in compliance
9*b0724fc6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b0724fc6SAndrew Rist  *
11*b0724fc6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b0724fc6SAndrew Rist  *
13*b0724fc6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b0724fc6SAndrew Rist  * software distributed under the License is distributed on an
15*b0724fc6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b0724fc6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b0724fc6SAndrew Rist  * specific language governing permissions and limitations
18*b0724fc6SAndrew Rist  * under the License.
19*b0724fc6SAndrew Rist  *
20*b0724fc6SAndrew Rist  *************************************************************/
21*b0724fc6SAndrew Rist 
22*b0724fc6SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "precompiled_toolkit.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "sortablegriddatamodel.hxx"
27cdf0e10cSrcweir #include "toolkit/helper/servicenames.hxx"
28cdf0e10cSrcweir 
29cdf0e10cSrcweir /** === begin UNO includes === **/
30cdf0e10cSrcweir #include <com/sun/star/i18n/XCollator.hpp>
31cdf0e10cSrcweir #include <com/sun/star/lang/IllegalArgumentException.hpp>
32cdf0e10cSrcweir #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
33cdf0e10cSrcweir /** === end UNO includes === **/
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <comphelper/anycompare.hxx>
36cdf0e10cSrcweir #include <cppuhelper/typeprovider.hxx>
37cdf0e10cSrcweir #include <tools/diagnose_ex.h>
38cdf0e10cSrcweir #include <tools/debug.hxx>
39cdf0e10cSrcweir #include <vcl/svapp.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <set>
42cdf0e10cSrcweir 
43cdf0e10cSrcweir //......................................................................................................................
44cdf0e10cSrcweir namespace toolkit
45cdf0e10cSrcweir {
46cdf0e10cSrcweir //......................................................................................................................
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 	/** === begin UNO using === **/
49cdf0e10cSrcweir     using ::com::sun::star::uno::TypeClass;
50cdf0e10cSrcweir     using ::com::sun::star::uno::TypeClass_VOID;
51cdf0e10cSrcweir 	using ::com::sun::star::uno::Reference;
52cdf0e10cSrcweir 	using ::com::sun::star::uno::XInterface;
53cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY;
54cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY_THROW;
55cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_SET_THROW;
56cdf0e10cSrcweir 	using ::com::sun::star::uno::Exception;
57cdf0e10cSrcweir 	using ::com::sun::star::uno::RuntimeException;
58cdf0e10cSrcweir 	using ::com::sun::star::uno::Any;
59cdf0e10cSrcweir 	using ::com::sun::star::uno::makeAny;
60cdf0e10cSrcweir 	using ::com::sun::star::uno::Sequence;
61cdf0e10cSrcweir 	using ::com::sun::star::uno::Type;
62cdf0e10cSrcweir     using ::com::sun::star::lang::IndexOutOfBoundsException;
63cdf0e10cSrcweir     using ::com::sun::star::lang::IllegalArgumentException;
64cdf0e10cSrcweir     using ::com::sun::star::awt::grid::XGridDataListener;
65cdf0e10cSrcweir     using ::com::sun::star::beans::Pair;
66cdf0e10cSrcweir     using ::com::sun::star::util::XCloneable;
67cdf0e10cSrcweir     using ::com::sun::star::i18n::XCollator;
68cdf0e10cSrcweir     using ::com::sun::star::lang::IllegalArgumentException;
69cdf0e10cSrcweir     using ::com::sun::star::lang::XMultiServiceFactory;
70cdf0e10cSrcweir     using ::com::sun::star::awt::grid::GridDataEvent;
71cdf0e10cSrcweir     using ::com::sun::star::lang::EventObject;
72cdf0e10cSrcweir     using ::com::sun::star::ucb::AlreadyInitializedException;
73cdf0e10cSrcweir 	/** === end UNO using === **/
74cdf0e10cSrcweir 
75cdf0e10cSrcweir #ifdef DBG_UTIL
SortableGridDataModel_checkInvariants(const void * _pInstance)76cdf0e10cSrcweir     const char* SortableGridDataModel_checkInvariants( const void* _pInstance )
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir         return static_cast< const SortableGridDataModel* >( _pInstance )->checkInvariants();
79cdf0e10cSrcweir     }
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
checkInvariants() const82cdf0e10cSrcweir     const char* SortableGridDataModel::checkInvariants() const
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         if ( m_publicToPrivateRowIndex.size() != m_privateToPublicRowIndex.size() )
85cdf0e10cSrcweir             return "inconsistent index maps";
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         if ( m_delegator.is() )
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             if ( m_publicToPrivateRowIndex.size() != size_t( m_delegator->getRowCount() ) )
90cdf0e10cSrcweir                 return "wrong cached row count";
91cdf0e10cSrcweir         }
92cdf0e10cSrcweir         else
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             if ( !m_publicToPrivateRowIndex.empty() )
95cdf0e10cSrcweir                 return "disposed or not initialized, but having a non-empty map";
96cdf0e10cSrcweir         }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir         for ( size_t publicIndex=0; publicIndex<m_publicToPrivateRowIndex.size(); ++publicIndex )
99cdf0e10cSrcweir         {
100cdf0e10cSrcweir             ::sal_Int32 const privateIndex = m_publicToPrivateRowIndex[ publicIndex ];
101cdf0e10cSrcweir             if ( ( privateIndex < 0 ) || ( size_t( privateIndex ) >= m_privateToPublicRowIndex.size() ) )
102cdf0e10cSrcweir                 return "invalid cached private index";
103cdf0e10cSrcweir 
104cdf0e10cSrcweir             if ( m_privateToPublicRowIndex[ privateIndex ] != sal_Int32( publicIndex ) )
105cdf0e10cSrcweir                 return "index map traversal not commutavive";
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir         if ( impl_isSorted_nothrow() && m_publicToPrivateRowIndex.empty() )
109cdf0e10cSrcweir             return "sorted, but no row index translation tables";
110cdf0e10cSrcweir 
111cdf0e10cSrcweir         if ( !impl_isSorted_nothrow() && !m_publicToPrivateRowIndex.empty() )
112cdf0e10cSrcweir             return "unsorted, but have index translation tables";
113cdf0e10cSrcweir 
114cdf0e10cSrcweir         return NULL;
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir #endif
117cdf0e10cSrcweir 
118cdf0e10cSrcweir #define DBG_CHECK_ME() \
119cdf0e10cSrcweir     DBG_CHKTHIS( SortableGridDataModel, SortableGridDataModel_checkInvariants )
120cdf0e10cSrcweir 
121cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
122cdf0e10cSrcweir     namespace
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         template< class STLCONTAINER >
lcl_clear(STLCONTAINER & i_container)125cdf0e10cSrcweir         static void lcl_clear( STLCONTAINER& i_container )
126cdf0e10cSrcweir         {
127cdf0e10cSrcweir             STLCONTAINER empty;
128cdf0e10cSrcweir             empty.swap( i_container );
129cdf0e10cSrcweir         }
130cdf0e10cSrcweir     }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir 	//==================================================================================================================
133cdf0e10cSrcweir 	//= SortableGridDataModel
134cdf0e10cSrcweir 	//==================================================================================================================
DBG_NAME(SortableGridDataModel)135cdf0e10cSrcweir     DBG_NAME( SortableGridDataModel )
136cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
137cdf0e10cSrcweir     SortableGridDataModel::SortableGridDataModel( Reference< XMultiServiceFactory > const & i_factory )
138cdf0e10cSrcweir         :SortableGridDataModel_Base( m_aMutex )
139cdf0e10cSrcweir         ,SortableGridDataModel_PrivateBase()
140cdf0e10cSrcweir         ,m_context( i_factory )
141cdf0e10cSrcweir         ,m_isInitialized( false )
142cdf0e10cSrcweir         ,m_delegator()
143cdf0e10cSrcweir         ,m_collator()
144cdf0e10cSrcweir         ,m_currentSortColumn( -1 )
145cdf0e10cSrcweir         ,m_sortAscending( true )
146cdf0e10cSrcweir         ,m_publicToPrivateRowIndex()
147cdf0e10cSrcweir         ,m_privateToPublicRowIndex()
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir         DBG_CTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
150cdf0e10cSrcweir     }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
SortableGridDataModel(SortableGridDataModel const & i_copySource)153cdf0e10cSrcweir     SortableGridDataModel::SortableGridDataModel( SortableGridDataModel const & i_copySource )
154cdf0e10cSrcweir         :cppu::BaseMutex()
155cdf0e10cSrcweir         ,SortableGridDataModel_Base( m_aMutex )
156cdf0e10cSrcweir         ,SortableGridDataModel_PrivateBase()
157cdf0e10cSrcweir         ,m_context( i_copySource.m_context )
158cdf0e10cSrcweir         ,m_isInitialized( true )
159cdf0e10cSrcweir         ,m_delegator()
160cdf0e10cSrcweir         ,m_collator( i_copySource.m_collator )
161cdf0e10cSrcweir         ,m_currentSortColumn( i_copySource.m_currentSortColumn )
162cdf0e10cSrcweir         ,m_sortAscending( i_copySource.m_sortAscending )
163cdf0e10cSrcweir         ,m_publicToPrivateRowIndex( i_copySource.m_publicToPrivateRowIndex )
164cdf0e10cSrcweir         ,m_privateToPublicRowIndex( i_copySource.m_privateToPublicRowIndex )
165cdf0e10cSrcweir     {
166cdf0e10cSrcweir         DBG_CTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir         ENSURE_OR_THROW( i_copySource.m_delegator.is(),
169cdf0e10cSrcweir             "not expected to be called for a disposed copy source!" );
170cdf0e10cSrcweir         m_delegator.set( i_copySource.m_delegator->createClone(), UNO_QUERY_THROW );
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir 	//------------------------------------------------------------------------------------------------------------------
~SortableGridDataModel()174cdf0e10cSrcweir     SortableGridDataModel::~SortableGridDataModel()
175cdf0e10cSrcweir     {
176cdf0e10cSrcweir         if ( !rBHelper.bDisposed )
177cdf0e10cSrcweir         {
178cdf0e10cSrcweir             acquire();
179cdf0e10cSrcweir             dispose();
180cdf0e10cSrcweir         }
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         DBG_DTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
183cdf0e10cSrcweir     }
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
queryInterface(const Type & aType)186cdf0e10cSrcweir     Any SAL_CALL SortableGridDataModel::queryInterface( const Type& aType ) throw (RuntimeException)
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         Any aReturn( SortableGridDataModel_Base::queryInterface( aType ) );
189cdf0e10cSrcweir         if ( !aReturn.hasValue() )
190cdf0e10cSrcweir             aReturn = SortableGridDataModel_PrivateBase::queryInterface( aType );
191cdf0e10cSrcweir         return aReturn;
192cdf0e10cSrcweir     }
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
acquire()195cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::acquire(  ) throw ()
196cdf0e10cSrcweir     {
197cdf0e10cSrcweir         SortableGridDataModel_Base::acquire();
198cdf0e10cSrcweir     }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
release()201cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::release(  ) throw ()
202cdf0e10cSrcweir     {
203cdf0e10cSrcweir         SortableGridDataModel_Base::release();
204cdf0e10cSrcweir     }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getTypes()207cdf0e10cSrcweir     Sequence< Type > SAL_CALL SortableGridDataModel::getTypes(  ) throw (RuntimeException)
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         return SortableGridDataModel_Base::getTypes();
210cdf0e10cSrcweir         // don't expose the types got via SortableGridDataModel_PrivateBase - they're private, after all
211cdf0e10cSrcweir     }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getImplementationId()214cdf0e10cSrcweir     Sequence< ::sal_Int8 > SAL_CALL SortableGridDataModel::getImplementationId(  ) throw (RuntimeException)
215cdf0e10cSrcweir     {
216cdf0e10cSrcweir         static ::cppu::OImplementationId aId;
217cdf0e10cSrcweir         return aId.getImplementationId();
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
221cdf0e10cSrcweir     namespace
222cdf0e10cSrcweir     {
lcl_loadDefaultCollator_throw(::comphelper::ComponentContext const & i_context)223cdf0e10cSrcweir         Reference< XCollator > lcl_loadDefaultCollator_throw( ::comphelper::ComponentContext const & i_context )
224cdf0e10cSrcweir         {
225cdf0e10cSrcweir             Reference< XCollator > const xCollator( i_context.createComponent( "com.sun.star.i18n.Collator" ), UNO_QUERY_THROW );
226cdf0e10cSrcweir 		    xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 );
227cdf0e10cSrcweir             return xCollator;
228cdf0e10cSrcweir         }
229cdf0e10cSrcweir     }
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
initialize(const Sequence<Any> & i_arguments)232cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::initialize( const Sequence< Any >& i_arguments ) throw (Exception, RuntimeException)
233cdf0e10cSrcweir     {
234cdf0e10cSrcweir         ::comphelper::ComponentGuard aGuard( *this, rBHelper );
235cdf0e10cSrcweir         DBG_CHECK_ME();
236cdf0e10cSrcweir 
237cdf0e10cSrcweir         if ( m_delegator.is() )
238cdf0e10cSrcweir             throw AlreadyInitializedException( ::rtl::OUString(), *this );
239cdf0e10cSrcweir 
240cdf0e10cSrcweir         Reference< XMutableGridDataModel > xDelegator;
241cdf0e10cSrcweir         Reference< XCollator > xCollator;
242cdf0e10cSrcweir         switch ( i_arguments.getLength() )
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir         case 1: // SortableGridDataModel.create( XMutableGridDataModel )
245cdf0e10cSrcweir             xDelegator.set( i_arguments[0], UNO_QUERY );
246cdf0e10cSrcweir             xCollator = lcl_loadDefaultCollator_throw( m_context );
247cdf0e10cSrcweir             break;
248cdf0e10cSrcweir 
249cdf0e10cSrcweir         case 2: // SortableGridDataModel.createWithCollator( XMutableGridDataModel, XCollator )
250cdf0e10cSrcweir             xDelegator.set( i_arguments[0], UNO_QUERY );
251cdf0e10cSrcweir             xCollator.set( i_arguments[1], UNO_QUERY );
252cdf0e10cSrcweir             if ( !xCollator.is() )
253cdf0e10cSrcweir                 throw IllegalArgumentException( ::rtl::OUString(), *this, 2 );
254cdf0e10cSrcweir             break;
255cdf0e10cSrcweir         }
256cdf0e10cSrcweir         if ( !xDelegator.is() )
257cdf0e10cSrcweir             throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
258cdf0e10cSrcweir 
259cdf0e10cSrcweir         m_delegator = xDelegator;
260cdf0e10cSrcweir         m_collator = xCollator;
261cdf0e10cSrcweir 
262cdf0e10cSrcweir         m_delegator->addGridDataListener( this );
263cdf0e10cSrcweir 
264cdf0e10cSrcweir         m_isInitialized = true;
265cdf0e10cSrcweir     }
266cdf0e10cSrcweir 
267cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_createPublicEvent(GridDataEvent const & i_originalEvent) const268cdf0e10cSrcweir     GridDataEvent SortableGridDataModel::impl_createPublicEvent( GridDataEvent const & i_originalEvent ) const
269cdf0e10cSrcweir     {
270cdf0e10cSrcweir         GridDataEvent aEvent( i_originalEvent );
271cdf0e10cSrcweir         aEvent.Source = *const_cast< SortableGridDataModel* >( this );
272cdf0e10cSrcweir         aEvent.FirstRow = impl_getPublicRowIndex_nothrow( aEvent.FirstRow );
273cdf0e10cSrcweir         aEvent.LastRow = impl_getPublicRowIndex_nothrow( aEvent.LastRow );
274cdf0e10cSrcweir         return aEvent;
275cdf0e10cSrcweir     }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_broadcast(void (SAL_CALL XGridDataListener::* i_listenerMethod)(const GridDataEvent &),GridDataEvent const & i_publicEvent,MethodGuard & i_instanceLock)278cdf0e10cSrcweir     void SortableGridDataModel::impl_broadcast( void ( SAL_CALL XGridDataListener::*i_listenerMethod )( const GridDataEvent & ),
279cdf0e10cSrcweir             GridDataEvent const & i_publicEvent, MethodGuard& i_instanceLock )
280cdf0e10cSrcweir     {
281cdf0e10cSrcweir         ::cppu::OInterfaceContainerHelper* pListeners = rBHelper.getContainer( XGridDataListener::static_type() );
282cdf0e10cSrcweir         if ( pListeners == NULL )
283cdf0e10cSrcweir             return;
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         i_instanceLock.clear();
286cdf0e10cSrcweir         pListeners->notifyEach( i_listenerMethod, i_publicEvent );
287cdf0e10cSrcweir     }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
rowsInserted(const GridDataEvent & i_event)290cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException)
291cdf0e10cSrcweir     {
292cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
293cdf0e10cSrcweir         DBG_CHECK_ME();
294cdf0e10cSrcweir 
295cdf0e10cSrcweir         if ( impl_isSorted_nothrow() )
296cdf0e10cSrcweir         {
297cdf0e10cSrcweir             // no infrastructure is in place currently to sort the new row to its proper location,
298cdf0e10cSrcweir             // so we remove the sorting here.
299cdf0e10cSrcweir             impl_removeColumnSort( aGuard );
300cdf0e10cSrcweir             aGuard.reset();
301cdf0e10cSrcweir         }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir         GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
304cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::rowsInserted, aEvent, aGuard );
305cdf0e10cSrcweir     }
306cdf0e10cSrcweir 
307cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
308cdf0e10cSrcweir     namespace
309cdf0e10cSrcweir     {
lcl_decrementValuesGreaterThan(::std::vector<::sal_Int32> & io_indexMap,sal_Int32 const i_threshold)310cdf0e10cSrcweir         void lcl_decrementValuesGreaterThan( ::std::vector< ::sal_Int32 > & io_indexMap, sal_Int32 const i_threshold )
311cdf0e10cSrcweir         {
312cdf0e10cSrcweir             for (   ::std::vector< ::sal_Int32 >::iterator loop = io_indexMap.begin();
313cdf0e10cSrcweir                     loop != io_indexMap.end();
314cdf0e10cSrcweir                     ++loop
315cdf0e10cSrcweir                 )
316cdf0e10cSrcweir             {
317cdf0e10cSrcweir                 if ( *loop >= i_threshold )
318cdf0e10cSrcweir                     --*loop;
319cdf0e10cSrcweir             }
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_rebuildIndexesAndNotify(MethodGuard & i_instanceLock)324cdf0e10cSrcweir     void SortableGridDataModel::impl_rebuildIndexesAndNotify( MethodGuard& i_instanceLock )
325cdf0e10cSrcweir     {
326cdf0e10cSrcweir         OSL_PRECOND( impl_isSorted_nothrow(), "SortableGridDataModel::impl_rebuildIndexesAndNotify: illegal call!" );
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         // clear the indexes
329cdf0e10cSrcweir         lcl_clear( m_publicToPrivateRowIndex );
330cdf0e10cSrcweir         lcl_clear( m_privateToPublicRowIndex );
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         // rebuild the index
333cdf0e10cSrcweir         if ( !impl_reIndex_nothrow( m_currentSortColumn, m_sortAscending ) )
334cdf0e10cSrcweir         {
335cdf0e10cSrcweir             impl_removeColumnSort( i_instanceLock );
336cdf0e10cSrcweir             return;
337cdf0e10cSrcweir         }
338cdf0e10cSrcweir 
339cdf0e10cSrcweir         // broadcast an artificial event, saying that all rows have been removed
340cdf0e10cSrcweir         GridDataEvent const aRemovalEvent( *this, -1, -1, -1, -1 );
341cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::rowsRemoved, aRemovalEvent, i_instanceLock );
342cdf0e10cSrcweir         i_instanceLock.reset();
343cdf0e10cSrcweir 
344cdf0e10cSrcweir         // broadcast an artificial event, saying that n rows have been added
345cdf0e10cSrcweir         GridDataEvent const aAdditionEvent( *this, -1, -1, 0, m_delegator->getRowCount() - 1 );
346cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::rowsInserted, aAdditionEvent, i_instanceLock );
347cdf0e10cSrcweir     }
348cdf0e10cSrcweir 
349cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
rowsRemoved(const GridDataEvent & i_event)350cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException)
351cdf0e10cSrcweir     {
352cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
353cdf0e10cSrcweir         DBG_CHECK_ME();
354cdf0e10cSrcweir 
355cdf0e10cSrcweir         // if the data is not sorted, broadcast the event unchanged
356cdf0e10cSrcweir         if ( !impl_isSorted_nothrow() )
357cdf0e10cSrcweir         {
358cdf0e10cSrcweir             GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
359cdf0e10cSrcweir             impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
360cdf0e10cSrcweir             return;
361cdf0e10cSrcweir         }
362cdf0e10cSrcweir 
363cdf0e10cSrcweir         // if all rows have been removed, also simply multiplex to own listeners
364cdf0e10cSrcweir         if ( i_event.FirstRow < 0 )
365cdf0e10cSrcweir         {
366cdf0e10cSrcweir             lcl_clear( m_publicToPrivateRowIndex );
367cdf0e10cSrcweir             lcl_clear( m_privateToPublicRowIndex );
368cdf0e10cSrcweir             GridDataEvent aEvent( i_event );
369cdf0e10cSrcweir             aEvent.Source = *this;
370cdf0e10cSrcweir             impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
371cdf0e10cSrcweir             return;
372cdf0e10cSrcweir         }
373cdf0e10cSrcweir 
374cdf0e10cSrcweir         bool needReIndex = false;
375cdf0e10cSrcweir         if ( i_event.FirstRow != i_event.LastRow )
376cdf0e10cSrcweir         {
377cdf0e10cSrcweir             OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: missing implementation - removal of multiple rows!" );
378cdf0e10cSrcweir             needReIndex = true;
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir         else if ( size_t( i_event.FirstRow ) >= m_privateToPublicRowIndex.size() )
381cdf0e10cSrcweir         {
382cdf0e10cSrcweir             OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: inconsistent/wrong data!" );
383cdf0e10cSrcweir             needReIndex = true;
384cdf0e10cSrcweir         }
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         if ( needReIndex )
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             impl_rebuildIndexesAndNotify( aGuard );
389cdf0e10cSrcweir             return;
390cdf0e10cSrcweir         }
391cdf0e10cSrcweir 
392cdf0e10cSrcweir         // build public event version
393cdf0e10cSrcweir         GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
394cdf0e10cSrcweir 
395cdf0e10cSrcweir         // remove the entries from the index maps
396cdf0e10cSrcweir         sal_Int32 const privateIndex = i_event.FirstRow;
397cdf0e10cSrcweir         sal_Int32 const publicIndex = aEvent.FirstRow;
398cdf0e10cSrcweir 
399cdf0e10cSrcweir         m_publicToPrivateRowIndex.erase( m_publicToPrivateRowIndex.begin() + publicIndex );
400cdf0e10cSrcweir         m_privateToPublicRowIndex.erase( m_privateToPublicRowIndex.begin() + privateIndex );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir         // adjust remaining entries in the index maps
403cdf0e10cSrcweir         lcl_decrementValuesGreaterThan( m_publicToPrivateRowIndex, privateIndex );
404cdf0e10cSrcweir         lcl_decrementValuesGreaterThan( m_privateToPublicRowIndex, publicIndex );
405cdf0e10cSrcweir 
406cdf0e10cSrcweir         // broadcast the event
407cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
408cdf0e10cSrcweir     }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
dataChanged(const GridDataEvent & i_event)411cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException)
412cdf0e10cSrcweir     {
413cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
414cdf0e10cSrcweir         DBG_CHECK_ME();
415cdf0e10cSrcweir 
416cdf0e10cSrcweir         GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
417cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::dataChanged, aEvent, aGuard );
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
rowHeadingChanged(const GridDataEvent & i_event)421cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException)
422cdf0e10cSrcweir     {
423cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
424cdf0e10cSrcweir         DBG_CHECK_ME();
425cdf0e10cSrcweir 
426cdf0e10cSrcweir         GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
427cdf0e10cSrcweir         impl_broadcast( &XGridDataListener::rowHeadingChanged, aEvent, aGuard );
428cdf0e10cSrcweir     }
429cdf0e10cSrcweir 
430cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
disposing(const EventObject & i_event)431cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::disposing( const EventObject& i_event ) throw (RuntimeException)
432cdf0e10cSrcweir     {
433cdf0e10cSrcweir         // not interested in
434cdf0e10cSrcweir         OSL_UNUSED( i_event );
435cdf0e10cSrcweir     }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
438cdf0e10cSrcweir     namespace
439cdf0e10cSrcweir     {
440cdf0e10cSrcweir         class CellDataLessComparison : public ::std::binary_function< sal_Int32, sal_Int32, bool >
441cdf0e10cSrcweir         {
442cdf0e10cSrcweir         public:
CellDataLessComparison(::std::vector<Any> const & i_data,::comphelper::IKeyPredicateLess & i_predicate,sal_Bool const i_sortAscending)443cdf0e10cSrcweir             CellDataLessComparison(
444cdf0e10cSrcweir                 ::std::vector< Any > const & i_data,
445cdf0e10cSrcweir                 ::comphelper::IKeyPredicateLess& i_predicate,
446cdf0e10cSrcweir                 sal_Bool const i_sortAscending
447cdf0e10cSrcweir             )
448cdf0e10cSrcweir                 :m_data( i_data )
449cdf0e10cSrcweir                 ,m_predicate( i_predicate )
450cdf0e10cSrcweir                 ,m_sortAscending( i_sortAscending )
451cdf0e10cSrcweir             {
452cdf0e10cSrcweir             }
453cdf0e10cSrcweir 
operator ()(sal_Int32 const i_lhs,sal_Int32 const i_rhs) const454cdf0e10cSrcweir             bool operator()( sal_Int32 const i_lhs, sal_Int32 const i_rhs ) const
455cdf0e10cSrcweir             {
456cdf0e10cSrcweir                 Any const & lhs = m_data[ i_lhs ];
457cdf0e10cSrcweir                 Any const & rhs = m_data[ i_rhs ];
458cdf0e10cSrcweir                 // <VOID/> is less than everything else
459cdf0e10cSrcweir                 if ( !lhs.hasValue() )
460cdf0e10cSrcweir                     return m_sortAscending;
461cdf0e10cSrcweir                 if ( !rhs.hasValue() )
462cdf0e10cSrcweir                     return !m_sortAscending;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir                 // actually compare
465cdf0e10cSrcweir                 if ( m_sortAscending )
466cdf0e10cSrcweir                     return m_predicate.isLess( lhs, rhs );
467cdf0e10cSrcweir                 else
468cdf0e10cSrcweir                     return m_predicate.isLess( rhs, lhs );
469cdf0e10cSrcweir             }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir         private:
472cdf0e10cSrcweir             ::std::vector< Any > const &            m_data;
473cdf0e10cSrcweir             ::comphelper::IKeyPredicateLess const & m_predicate;
474cdf0e10cSrcweir             sal_Bool const                          m_sortAscending;
475cdf0e10cSrcweir         };
476cdf0e10cSrcweir     }
477cdf0e10cSrcweir 
478cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_reIndex_nothrow(::sal_Int32 const i_columnIndex,sal_Bool const i_sortAscending)479cdf0e10cSrcweir     bool SortableGridDataModel::impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending )
480cdf0e10cSrcweir     {
481cdf0e10cSrcweir         ::sal_Int32 const rowCount( getRowCount() );
482cdf0e10cSrcweir         ::std::vector< ::sal_Int32 > aPublicToPrivate( rowCount );
483cdf0e10cSrcweir 
484cdf0e10cSrcweir         try
485cdf0e10cSrcweir         {
486cdf0e10cSrcweir             // build an unsorted translation table, and retrieve the unsorted data
487cdf0e10cSrcweir             ::std::vector< Any > aColumnData( rowCount );
488cdf0e10cSrcweir             Type dataType;
489cdf0e10cSrcweir             for ( ::sal_Int32 rowIndex = 0; rowIndex < rowCount; ++rowIndex )
490cdf0e10cSrcweir             {
491cdf0e10cSrcweir                 aColumnData[ rowIndex ] = m_delegator->getCellData( i_columnIndex, rowIndex );
492cdf0e10cSrcweir                 aPublicToPrivate[ rowIndex ] = rowIndex;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir                 // determine the data types we assume for the complete column
495cdf0e10cSrcweir                 if ( ( dataType.getTypeClass() == TypeClass_VOID ) && aColumnData[ rowIndex ].hasValue() )
496cdf0e10cSrcweir                     dataType = aColumnData[ rowIndex ].getValueType();
497cdf0e10cSrcweir             }
498cdf0e10cSrcweir 
499cdf0e10cSrcweir             // get predicate object
500cdf0e10cSrcweir             ::std::auto_ptr< ::comphelper::IKeyPredicateLess > const pPredicate( ::comphelper::getStandardLessPredicate( dataType, m_collator ) );
501cdf0e10cSrcweir             ENSURE_OR_RETURN_FALSE( pPredicate.get(), "SortableGridDataModel::impl_reIndex_nothrow: no sortable data found!" );
502cdf0e10cSrcweir 
503cdf0e10cSrcweir             // then sort
504cdf0e10cSrcweir             CellDataLessComparison const aComparator( aColumnData, *pPredicate, i_sortAscending );
505cdf0e10cSrcweir             ::std::sort( aPublicToPrivate.begin(), aPublicToPrivate.end(), aComparator );
506cdf0e10cSrcweir         }
507cdf0e10cSrcweir         catch( const Exception& )
508cdf0e10cSrcweir         {
509cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
510cdf0e10cSrcweir             return false;
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir         // also build the "private to public" mapping
514cdf0e10cSrcweir         ::std::vector< sal_Int32 > aPrivateToPublic( aPublicToPrivate.size() );
515cdf0e10cSrcweir         for ( size_t i=0; i<aPublicToPrivate.size(); ++i )
516cdf0e10cSrcweir             aPrivateToPublic[ aPublicToPrivate[i] ] = i;
517cdf0e10cSrcweir 
518cdf0e10cSrcweir         m_publicToPrivateRowIndex.swap( aPublicToPrivate );
519cdf0e10cSrcweir         m_privateToPublicRowIndex.swap( aPrivateToPublic );
520cdf0e10cSrcweir 
521cdf0e10cSrcweir         return true;
522cdf0e10cSrcweir     }
523cdf0e10cSrcweir 
524cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
sortByColumn(::sal_Int32 i_columnIndex,::sal_Bool i_sortAscending)525cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::sortByColumn( ::sal_Int32 i_columnIndex, ::sal_Bool i_sortAscending ) throw (IndexOutOfBoundsException, RuntimeException)
526cdf0e10cSrcweir     {
527cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
528cdf0e10cSrcweir         DBG_CHECK_ME();
529cdf0e10cSrcweir 
530cdf0e10cSrcweir         if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= getColumnCount() ) )
531cdf0e10cSrcweir             throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
532cdf0e10cSrcweir 
533cdf0e10cSrcweir         if ( !impl_reIndex_nothrow( i_columnIndex, i_sortAscending ) )
534cdf0e10cSrcweir             return;
535cdf0e10cSrcweir 
536cdf0e10cSrcweir         m_currentSortColumn = i_columnIndex;
537cdf0e10cSrcweir         m_sortAscending = i_sortAscending;
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         impl_broadcast(
540cdf0e10cSrcweir             &XGridDataListener::dataChanged,
541cdf0e10cSrcweir             GridDataEvent( *this, -1, -1, -1, -1 ),
542cdf0e10cSrcweir             aGuard
543cdf0e10cSrcweir         );
544cdf0e10cSrcweir     }
545cdf0e10cSrcweir 
546cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_removeColumnSort_noBroadcast()547cdf0e10cSrcweir     void SortableGridDataModel::impl_removeColumnSort_noBroadcast()
548cdf0e10cSrcweir     {
549cdf0e10cSrcweir         lcl_clear( m_publicToPrivateRowIndex );
550cdf0e10cSrcweir         lcl_clear( m_privateToPublicRowIndex );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir         m_currentSortColumn = -1;
553cdf0e10cSrcweir         m_sortAscending = sal_True;
554cdf0e10cSrcweir     }
555cdf0e10cSrcweir 
556cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_removeColumnSort(MethodGuard & i_instanceLock)557cdf0e10cSrcweir     void SortableGridDataModel::impl_removeColumnSort( MethodGuard& i_instanceLock )
558cdf0e10cSrcweir     {
559cdf0e10cSrcweir         impl_removeColumnSort_noBroadcast();
560cdf0e10cSrcweir         impl_broadcast(
561cdf0e10cSrcweir             &XGridDataListener::dataChanged,
562cdf0e10cSrcweir             GridDataEvent( *this, -1, -1, -1, -1 ),
563cdf0e10cSrcweir             i_instanceLock
564cdf0e10cSrcweir         );
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir 
567cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
removeColumnSort()568cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::removeColumnSort(  ) throw (RuntimeException)
569cdf0e10cSrcweir     {
570cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
571cdf0e10cSrcweir         DBG_CHECK_ME();
572cdf0e10cSrcweir         impl_removeColumnSort( aGuard );
573cdf0e10cSrcweir     }
574cdf0e10cSrcweir 
575cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getCurrentSortOrder()576cdf0e10cSrcweir     Pair< ::sal_Int32, ::sal_Bool > SAL_CALL SortableGridDataModel::getCurrentSortOrder(  ) throw (RuntimeException)
577cdf0e10cSrcweir     {
578cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
579cdf0e10cSrcweir         DBG_CHECK_ME();
580cdf0e10cSrcweir 
581cdf0e10cSrcweir         return Pair< ::sal_Int32, ::sal_Bool >( m_currentSortColumn, m_sortAscending );
582cdf0e10cSrcweir     }
583cdf0e10cSrcweir 
584cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
addRow(const Any & i_heading,const Sequence<Any> & i_data)585cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::addRow( const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException)
586cdf0e10cSrcweir     {
587cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
588cdf0e10cSrcweir         DBG_CHECK_ME();
589cdf0e10cSrcweir 
590cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
591cdf0e10cSrcweir         aGuard.clear();
592cdf0e10cSrcweir         delegator->addRow( i_heading, i_data );
593cdf0e10cSrcweir     }
594cdf0e10cSrcweir 
595cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
addRows(const Sequence<Any> & i_headings,const Sequence<Sequence<Any>> & i_data)596cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::addRows( const Sequence< Any >& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, RuntimeException)
597cdf0e10cSrcweir     {
598cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
599cdf0e10cSrcweir         DBG_CHECK_ME();
600cdf0e10cSrcweir 
601cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
602cdf0e10cSrcweir         aGuard.clear();
603cdf0e10cSrcweir         delegator->addRows( i_headings, i_data );
604cdf0e10cSrcweir     }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
insertRow(::sal_Int32 i_index,const Any & i_heading,const Sequence<Any> & i_data)607cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::insertRow( ::sal_Int32 i_index, const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException, IndexOutOfBoundsException)
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
610cdf0e10cSrcweir         DBG_CHECK_ME();
611cdf0e10cSrcweir 
612cdf0e10cSrcweir         ::sal_Int32 const rowIndex = i_index == getRowCount() ? i_index : impl_getPrivateRowIndex_throw( i_index );
613cdf0e10cSrcweir             // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
614cdf0e10cSrcweir 
615cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
616cdf0e10cSrcweir         aGuard.clear();
617cdf0e10cSrcweir         delegator->insertRow( rowIndex, i_heading, i_data );
618cdf0e10cSrcweir     }
619cdf0e10cSrcweir 
620cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
insertRows(::sal_Int32 i_index,const Sequence<Any> & i_headings,const Sequence<Sequence<Any>> & i_data)621cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::insertRows( ::sal_Int32 i_index, const Sequence< Any>& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, IndexOutOfBoundsException, RuntimeException)
622cdf0e10cSrcweir     {
623cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
624cdf0e10cSrcweir         DBG_CHECK_ME();
625cdf0e10cSrcweir 
626cdf0e10cSrcweir         ::sal_Int32 const rowIndex = i_index == getRowCount() ? i_index : impl_getPrivateRowIndex_throw( i_index );
627cdf0e10cSrcweir             // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
628cdf0e10cSrcweir 
629cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
630cdf0e10cSrcweir         aGuard.clear();
631cdf0e10cSrcweir         delegator->insertRows( rowIndex, i_headings, i_data );
632cdf0e10cSrcweir     }
633cdf0e10cSrcweir 
634cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
removeRow(::sal_Int32 i_rowIndex)635cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::removeRow( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
636cdf0e10cSrcweir     {
637cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
638cdf0e10cSrcweir         DBG_CHECK_ME();
639cdf0e10cSrcweir 
640cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
641cdf0e10cSrcweir 
642cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
643cdf0e10cSrcweir         aGuard.clear();
644cdf0e10cSrcweir         delegator->removeRow( rowIndex );
645cdf0e10cSrcweir     }
646cdf0e10cSrcweir 
647cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
removeAllRows()648cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::removeAllRows(  ) throw (RuntimeException)
649cdf0e10cSrcweir     {
650cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
651cdf0e10cSrcweir         DBG_CHECK_ME();
652cdf0e10cSrcweir 
653cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
654cdf0e10cSrcweir         aGuard.clear();
655cdf0e10cSrcweir         delegator->removeAllRows();
656cdf0e10cSrcweir     }
657cdf0e10cSrcweir 
658cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
updateCellData(::sal_Int32 i_columnIndex,::sal_Int32 i_rowIndex,const Any & i_value)659cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::updateCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
660cdf0e10cSrcweir     {
661cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
662cdf0e10cSrcweir         DBG_CHECK_ME();
663cdf0e10cSrcweir 
664cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
667cdf0e10cSrcweir         aGuard.clear();
668cdf0e10cSrcweir         delegator->updateCellData( i_columnIndex, rowIndex, i_value );
669cdf0e10cSrcweir     }
670cdf0e10cSrcweir 
671cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
updateRowData(const Sequence<::sal_Int32> & i_columnIndexes,::sal_Int32 i_rowIndex,const Sequence<Any> & i_values)672cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::updateRowData( const Sequence< ::sal_Int32 >& i_columnIndexes, ::sal_Int32 i_rowIndex, const Sequence< Any >& i_values ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
673cdf0e10cSrcweir     {
674cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
675cdf0e10cSrcweir         DBG_CHECK_ME();
676cdf0e10cSrcweir 
677cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
678cdf0e10cSrcweir 
679cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
680cdf0e10cSrcweir         aGuard.clear();
681cdf0e10cSrcweir         delegator->updateRowData( i_columnIndexes, rowIndex, i_values );
682cdf0e10cSrcweir     }
683cdf0e10cSrcweir 
684cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
updateRowHeading(::sal_Int32 i_rowIndex,const Any & i_heading)685cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::updateRowHeading( ::sal_Int32 i_rowIndex, const Any& i_heading ) throw (IndexOutOfBoundsException, RuntimeException)
686cdf0e10cSrcweir     {
687cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
688cdf0e10cSrcweir         DBG_CHECK_ME();
689cdf0e10cSrcweir 
690cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
693cdf0e10cSrcweir         aGuard.clear();
694cdf0e10cSrcweir         delegator->updateRowHeading( rowIndex, i_heading );
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
updateCellToolTip(::sal_Int32 i_columnIndex,::sal_Int32 i_rowIndex,const Any & i_value)698cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::updateCellToolTip( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
699cdf0e10cSrcweir     {
700cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
701cdf0e10cSrcweir         DBG_CHECK_ME();
702cdf0e10cSrcweir 
703cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
704cdf0e10cSrcweir 
705cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
706cdf0e10cSrcweir         aGuard.clear();
707cdf0e10cSrcweir         delegator->updateCellToolTip( i_columnIndex, rowIndex, i_value );
708cdf0e10cSrcweir     }
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
updateRowToolTip(::sal_Int32 i_rowIndex,const Any & i_value)711cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::updateRowToolTip( ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
712cdf0e10cSrcweir     {
713cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
714cdf0e10cSrcweir         DBG_CHECK_ME();
715cdf0e10cSrcweir 
716cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
717cdf0e10cSrcweir 
718cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
719cdf0e10cSrcweir         aGuard.clear();
720cdf0e10cSrcweir         delegator->updateRowToolTip( rowIndex, i_value );
721cdf0e10cSrcweir     }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
addGridDataListener(const Reference<XGridDataListener> & i_listener)724cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::addGridDataListener( const Reference< XGridDataListener >& i_listener ) throw (RuntimeException)
725cdf0e10cSrcweir     {
726cdf0e10cSrcweir 	    rBHelper.addListener( XGridDataListener::static_type(), i_listener );
727cdf0e10cSrcweir     }
728cdf0e10cSrcweir 
729cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
removeGridDataListener(const Reference<XGridDataListener> & i_listener)730cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::removeGridDataListener( const Reference< XGridDataListener >& i_listener ) throw (RuntimeException)
731cdf0e10cSrcweir     {
732cdf0e10cSrcweir 	    rBHelper.removeListener( XGridDataListener::static_type(), i_listener );
733cdf0e10cSrcweir     }
734cdf0e10cSrcweir 
735cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getRowCount()736cdf0e10cSrcweir     ::sal_Int32 SAL_CALL SortableGridDataModel::getRowCount() throw (RuntimeException)
737cdf0e10cSrcweir     {
738cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
739cdf0e10cSrcweir         DBG_CHECK_ME();
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
742cdf0e10cSrcweir         aGuard.clear();
743cdf0e10cSrcweir         return delegator->getRowCount();
744cdf0e10cSrcweir     }
745cdf0e10cSrcweir 
746cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getColumnCount()747cdf0e10cSrcweir     ::sal_Int32 SAL_CALL SortableGridDataModel::getColumnCount() throw (RuntimeException)
748cdf0e10cSrcweir     {
749cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
750cdf0e10cSrcweir         DBG_CHECK_ME();
751cdf0e10cSrcweir 
752cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
753cdf0e10cSrcweir         aGuard.clear();
754cdf0e10cSrcweir         return delegator->getColumnCount();
755cdf0e10cSrcweir     }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getCellData(::sal_Int32 i_columnIndex,::sal_Int32 i_rowIndex)758cdf0e10cSrcweir     Any SAL_CALL SortableGridDataModel::getCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
759cdf0e10cSrcweir     {
760cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
761cdf0e10cSrcweir         DBG_CHECK_ME();
762cdf0e10cSrcweir 
763cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
764cdf0e10cSrcweir 
765cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
766cdf0e10cSrcweir         aGuard.clear();
767cdf0e10cSrcweir         return delegator->getCellData( i_columnIndex, rowIndex );
768cdf0e10cSrcweir     }
769cdf0e10cSrcweir 
770cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getCellToolTip(::sal_Int32 i_columnIndex,::sal_Int32 i_rowIndex)771cdf0e10cSrcweir     Any SAL_CALL SortableGridDataModel::getCellToolTip( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
772cdf0e10cSrcweir     {
773cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
774cdf0e10cSrcweir         DBG_CHECK_ME();
775cdf0e10cSrcweir 
776cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
777cdf0e10cSrcweir 
778cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
779cdf0e10cSrcweir         aGuard.clear();
780cdf0e10cSrcweir         return delegator->getCellToolTip( i_columnIndex, rowIndex );
781cdf0e10cSrcweir     }
782cdf0e10cSrcweir 
783cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getRowHeading(::sal_Int32 i_rowIndex)784cdf0e10cSrcweir     Any SAL_CALL SortableGridDataModel::getRowHeading( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
785cdf0e10cSrcweir     {
786cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
787cdf0e10cSrcweir         DBG_CHECK_ME();
788cdf0e10cSrcweir 
789cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
790cdf0e10cSrcweir 
791cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
792cdf0e10cSrcweir         aGuard.clear();
793cdf0e10cSrcweir         return delegator->getRowHeading( rowIndex );
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir 
796cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getRowData(::sal_Int32 i_rowIndex)797cdf0e10cSrcweir     Sequence< Any > SAL_CALL SortableGridDataModel::getRowData( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
798cdf0e10cSrcweir     {
799cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
800cdf0e10cSrcweir         DBG_CHECK_ME();
801cdf0e10cSrcweir 
802cdf0e10cSrcweir         ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
803cdf0e10cSrcweir 
804cdf0e10cSrcweir         Reference< XMutableGridDataModel > const delegator( m_delegator );
805cdf0e10cSrcweir         aGuard.clear();
806cdf0e10cSrcweir         return delegator->getRowData( rowIndex );
807cdf0e10cSrcweir     }
808cdf0e10cSrcweir 
809cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
disposing()810cdf0e10cSrcweir     void SAL_CALL SortableGridDataModel::disposing()
811cdf0e10cSrcweir     {
812cdf0e10cSrcweir         m_currentSortColumn = -1;
813cdf0e10cSrcweir 
814cdf0e10cSrcweir         Reference< XComponent > const delegatorComponent( m_delegator.get() );
815cdf0e10cSrcweir         m_delegator->removeGridDataListener( this );
816cdf0e10cSrcweir         m_delegator.clear();
817cdf0e10cSrcweir         delegatorComponent->dispose();
818cdf0e10cSrcweir 
819cdf0e10cSrcweir         Reference< XComponent > const collatorComponent( m_collator, UNO_QUERY );
820cdf0e10cSrcweir         m_collator.clear();
821cdf0e10cSrcweir         if ( collatorComponent.is() )
822cdf0e10cSrcweir             collatorComponent->dispose();
823cdf0e10cSrcweir 
824cdf0e10cSrcweir         lcl_clear( m_publicToPrivateRowIndex );
825cdf0e10cSrcweir         lcl_clear( m_privateToPublicRowIndex );
826cdf0e10cSrcweir     }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
createClone()829cdf0e10cSrcweir     Reference< XCloneable > SAL_CALL SortableGridDataModel::createClone(  ) throw (RuntimeException)
830cdf0e10cSrcweir     {
831cdf0e10cSrcweir         MethodGuard aGuard( *this, rBHelper );
832cdf0e10cSrcweir         DBG_CHECK_ME();
833cdf0e10cSrcweir 
834cdf0e10cSrcweir         return new SortableGridDataModel( *this );
835cdf0e10cSrcweir     }
836cdf0e10cSrcweir 
837cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getImplementationName()838cdf0e10cSrcweir     ::rtl::OUString SAL_CALL SortableGridDataModel::getImplementationName(  ) throw (RuntimeException)
839cdf0e10cSrcweir     {
840cdf0e10cSrcweir         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.toolkit.SortableGridDataModel" ) );
841cdf0e10cSrcweir     }
842cdf0e10cSrcweir 
843cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
supportsService(const::rtl::OUString & i_serviceName)844cdf0e10cSrcweir     ::sal_Bool SAL_CALL SortableGridDataModel::supportsService( const ::rtl::OUString& i_serviceName ) throw (RuntimeException)
845cdf0e10cSrcweir     {
846cdf0e10cSrcweir         Sequence< ::rtl::OUString > const aServiceNames( getSupportedServiceNames() );
847cdf0e10cSrcweir         for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
848cdf0e10cSrcweir             if ( aServiceNames[i] == i_serviceName )
849cdf0e10cSrcweir                 return sal_True;
850cdf0e10cSrcweir         return sal_False;
851cdf0e10cSrcweir     }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
getSupportedServiceNames()854cdf0e10cSrcweir     Sequence< ::rtl::OUString > SAL_CALL SortableGridDataModel::getSupportedServiceNames(  ) throw (RuntimeException)
855cdf0e10cSrcweir     {
856cdf0e10cSrcweir         Sequence< ::rtl::OUString > aServiceNames(1);
857cdf0e10cSrcweir         aServiceNames[0] = ::rtl::OUString::createFromAscii( szServiceName_SortableGridDataModel );
858cdf0e10cSrcweir         return aServiceNames;
859cdf0e10cSrcweir     }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_getPrivateRowIndex_throw(::sal_Int32 const i_publicRowIndex) const862cdf0e10cSrcweir     ::sal_Int32 SortableGridDataModel::impl_getPrivateRowIndex_throw( ::sal_Int32 const i_publicRowIndex ) const
863cdf0e10cSrcweir     {
864cdf0e10cSrcweir         if ( ( i_publicRowIndex < 0 ) || ( i_publicRowIndex >= m_delegator->getRowCount() ) )
865cdf0e10cSrcweir             throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SortableGridDataModel* >( this ) );
866cdf0e10cSrcweir 
867cdf0e10cSrcweir         if ( !impl_isSorted_nothrow() )
868cdf0e10cSrcweir             // no need to translate anything
869cdf0e10cSrcweir             return i_publicRowIndex;
870cdf0e10cSrcweir 
871cdf0e10cSrcweir         ENSURE_OR_RETURN( size_t( i_publicRowIndex ) < m_publicToPrivateRowIndex.size(),
872cdf0e10cSrcweir             "SortableGridDataModel::impl_getPrivateRowIndex_throw: inconsistency!", i_publicRowIndex );
873cdf0e10cSrcweir                 // obviously the translation table contains too few elements - it should have exactly |getRowCount()|
874cdf0e10cSrcweir                 // elements
875cdf0e10cSrcweir 
876cdf0e10cSrcweir         return m_publicToPrivateRowIndex[ i_publicRowIndex ];
877cdf0e10cSrcweir     }
878cdf0e10cSrcweir 
879cdf0e10cSrcweir     //------------------------------------------------------------------------------------------------------------------
impl_getPublicRowIndex_nothrow(::sal_Int32 const i_privateRowIndex) const880cdf0e10cSrcweir     ::sal_Int32 SortableGridDataModel::impl_getPublicRowIndex_nothrow( ::sal_Int32 const i_privateRowIndex ) const
881cdf0e10cSrcweir     {
882cdf0e10cSrcweir         if ( !impl_isSorted_nothrow() )
883cdf0e10cSrcweir             // no need to translate anything
884cdf0e10cSrcweir             return i_privateRowIndex;
885cdf0e10cSrcweir 
886cdf0e10cSrcweir         if ( i_privateRowIndex < 0 )
887cdf0e10cSrcweir             return i_privateRowIndex;
888cdf0e10cSrcweir 
889cdf0e10cSrcweir         ENSURE_OR_RETURN( size_t( i_privateRowIndex ) < m_privateToPublicRowIndex.size(),
890cdf0e10cSrcweir             "SortableGridDataModel::impl_getPublicRowIndex_nothrow: invalid index!", i_privateRowIndex );
891cdf0e10cSrcweir 
892cdf0e10cSrcweir         return m_privateToPublicRowIndex[ i_privateRowIndex ];
893cdf0e10cSrcweir     }
894cdf0e10cSrcweir 
895cdf0e10cSrcweir //......................................................................................................................
896cdf0e10cSrcweir } // namespace toolkit
897cdf0e10cSrcweir //......................................................................................................................
898cdf0e10cSrcweir 
SortableGridDataModel_CreateInstance(const::com::sun::star::uno::Reference<::com::sun::star::lang::XMultiServiceFactory> & i_factory)899cdf0e10cSrcweir ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL SortableGridDataModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory )
900cdf0e10cSrcweir {
901cdf0e10cSrcweir     return *( new ::toolkit::SortableGridDataModel( i_factory ) );
902cdf0e10cSrcweir }
903