LCOV - code coverage report
Current view: top level - toolkit/source/controls/grid - sortablegriddatamodel.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 245 354 69.2 %
Date: 2015-06-13 12:38:46 Functions: 44 58 75.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11