1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "sortablegriddatamodel.hxx"
22 #include "toolkit/helper/servicenames.hxx"
24 #include <com/sun/star/i18n/Collator.hpp>
25 #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 #include <com/sun/star/ucb/AlreadyInitializedException.hpp>
28 #include <comphelper/anycompare.hxx>
29 #include <comphelper/processfactory.hxx>
30 #include <cppuhelper/typeprovider.hxx>
31 #include <tools/diagnose_ex.h>
32 #include <tools/debug.hxx>
33 #include <vcl/svapp.hxx>
37 //......................................................................................................................
40 //......................................................................................................................
42 using ::com::sun::star::uno::TypeClass
;
43 using ::com::sun::star::uno::TypeClass_VOID
;
44 using ::com::sun::star::uno::Reference
;
45 using ::com::sun::star::uno::XInterface
;
46 using ::com::sun::star::uno::UNO_QUERY
;
47 using ::com::sun::star::uno::UNO_QUERY_THROW
;
48 using ::com::sun::star::uno::UNO_SET_THROW
;
49 using ::com::sun::star::uno::Exception
;
50 using ::com::sun::star::uno::RuntimeException
;
51 using ::com::sun::star::uno::Any
;
52 using ::com::sun::star::uno::makeAny
;
53 using ::com::sun::star::uno::Sequence
;
54 using ::com::sun::star::uno::Type
;
55 using ::com::sun::star::uno::XComponentContext
;
56 using ::com::sun::star::lang::IndexOutOfBoundsException
;
57 using ::com::sun::star::lang::IllegalArgumentException
;
58 using ::com::sun::star::awt::grid::XGridDataListener
;
59 using ::com::sun::star::beans::Pair
;
60 using ::com::sun::star::util::XCloneable
;
61 using ::com::sun::star::i18n::XCollator
;
62 using ::com::sun::star::i18n::Collator
;
63 using ::com::sun::star::lang::XMultiServiceFactory
;
64 using ::com::sun::star::awt::grid::GridDataEvent
;
65 using ::com::sun::star::lang::EventObject
;
66 using ::com::sun::star::ucb::AlreadyInitializedException
;
69 const char* SortableGridDataModel_checkInvariants( const void* _pInstance
)
71 return static_cast< const SortableGridDataModel
* >( _pInstance
)->checkInvariants();
74 //------------------------------------------------------------------------------------------------------------------
75 const char* SortableGridDataModel::checkInvariants() const
77 if ( m_publicToPrivateRowIndex
.size() != m_privateToPublicRowIndex
.size() )
78 return "inconsistent index maps";
80 if ( m_delegator
.is() )
82 if ( m_publicToPrivateRowIndex
.size() != size_t( m_delegator
->getRowCount() ) )
83 return "wrong cached row count";
87 if ( !m_publicToPrivateRowIndex
.empty() )
88 return "disposed or not initialized, but having a non-empty map";
91 for ( size_t publicIndex
=0; publicIndex
<m_publicToPrivateRowIndex
.size(); ++publicIndex
)
93 ::sal_Int32
const privateIndex
= m_publicToPrivateRowIndex
[ publicIndex
];
94 if ( ( privateIndex
< 0 ) || ( size_t( privateIndex
) >= m_privateToPublicRowIndex
.size() ) )
95 return "invalid cached private index";
97 if ( m_privateToPublicRowIndex
[ privateIndex
] != sal_Int32( publicIndex
) )
98 return "index map traversal not commutavive";
101 if ( impl_isSorted_nothrow() && m_publicToPrivateRowIndex
.empty() )
102 return "sorted, but no row index translation tables";
104 if ( !impl_isSorted_nothrow() && !m_publicToPrivateRowIndex
.empty() )
105 return "unsorted, but have index translation tables";
111 #define DBG_CHECK_ME() \
112 DBG_CHKTHIS( SortableGridDataModel, SortableGridDataModel_checkInvariants )
114 //------------------------------------------------------------------------------------------------------------------
117 template< class STLCONTAINER
>
118 static void lcl_clear( STLCONTAINER
& i_container
)
121 empty
.swap( i_container
);
125 //==================================================================================================================
126 //= SortableGridDataModel
127 //==================================================================================================================
128 DBG_NAME( SortableGridDataModel
)
129 //------------------------------------------------------------------------------------------------------------------
130 SortableGridDataModel::SortableGridDataModel( Reference
< XComponentContext
> const & rxContext
)
131 :SortableGridDataModel_Base( m_aMutex
)
132 ,SortableGridDataModel_PrivateBase()
133 ,m_xContext( rxContext
)
134 ,m_isInitialized( false )
137 ,m_currentSortColumn( -1 )
138 ,m_sortAscending( true )
139 ,m_publicToPrivateRowIndex()
140 ,m_privateToPublicRowIndex()
142 DBG_CTOR( SortableGridDataModel
, SortableGridDataModel_checkInvariants
);
145 //------------------------------------------------------------------------------------------------------------------
146 SortableGridDataModel::SortableGridDataModel( SortableGridDataModel
const & i_copySource
)
148 ,SortableGridDataModel_Base( m_aMutex
)
149 ,SortableGridDataModel_PrivateBase()
150 ,m_xContext( i_copySource
.m_xContext
)
151 ,m_isInitialized( true )
153 ,m_collator( i_copySource
.m_collator
)
154 ,m_currentSortColumn( i_copySource
.m_currentSortColumn
)
155 ,m_sortAscending( i_copySource
.m_sortAscending
)
156 ,m_publicToPrivateRowIndex( i_copySource
.m_publicToPrivateRowIndex
)
157 ,m_privateToPublicRowIndex( i_copySource
.m_privateToPublicRowIndex
)
159 DBG_CTOR( SortableGridDataModel
, SortableGridDataModel_checkInvariants
);
161 ENSURE_OR_THROW( i_copySource
.m_delegator
.is(),
162 "not expected to be called for a disposed copy source!" );
163 m_delegator
.set( i_copySource
.m_delegator
->createClone(), UNO_QUERY_THROW
);
166 //------------------------------------------------------------------------------------------------------------------
167 SortableGridDataModel::~SortableGridDataModel()
169 if ( !rBHelper
.bDisposed
)
175 DBG_DTOR( SortableGridDataModel
, SortableGridDataModel_checkInvariants
);
178 //------------------------------------------------------------------------------------------------------------------
179 Any SAL_CALL
SortableGridDataModel::queryInterface( const Type
& aType
) throw (RuntimeException
)
181 Any
aReturn( SortableGridDataModel_Base::queryInterface( aType
) );
182 if ( !aReturn
.hasValue() )
183 aReturn
= SortableGridDataModel_PrivateBase::queryInterface( aType
);
187 //------------------------------------------------------------------------------------------------------------------
188 void SAL_CALL
SortableGridDataModel::acquire( ) throw ()
190 SortableGridDataModel_Base::acquire();
193 //------------------------------------------------------------------------------------------------------------------
194 void SAL_CALL
SortableGridDataModel::release( ) throw ()
196 SortableGridDataModel_Base::release();
199 //------------------------------------------------------------------------------------------------------------------
200 Sequence
< Type
> SAL_CALL
SortableGridDataModel::getTypes( ) throw (RuntimeException
)
202 return SortableGridDataModel_Base::getTypes();
203 // don't expose the types got via SortableGridDataModel_PrivateBase - they're private, after all
206 //------------------------------------------------------------------------------------------------------------------
207 Sequence
< ::sal_Int8
> SAL_CALL
SortableGridDataModel::getImplementationId( ) throw (RuntimeException
)
209 static ::cppu::OImplementationId aId
;
210 return aId
.getImplementationId();
213 //------------------------------------------------------------------------------------------------------------------
216 Reference
< XCollator
> lcl_loadDefaultCollator_throw( const Reference
<XComponentContext
> & rxContext
)
218 Reference
< XCollator
> const xCollator
= Collator::create( rxContext
);
219 xCollator
->loadDefaultCollator( Application::GetSettings().GetLanguageTag().getLocale(), 0 );
224 //------------------------------------------------------------------------------------------------------------------
225 void SAL_CALL
SortableGridDataModel::initialize( const Sequence
< Any
>& i_arguments
) throw (Exception
, RuntimeException
)
227 ::comphelper::ComponentGuard
aGuard( *this, rBHelper
);
230 if ( m_delegator
.is() )
231 throw AlreadyInitializedException( OUString(), *this );
233 Reference
< XMutableGridDataModel
> xDelegator
;
234 Reference
< XCollator
> xCollator
;
235 switch ( i_arguments
.getLength() )
237 case 1: // SortableGridDataModel.create( XMutableGridDataModel )
238 xDelegator
.set( i_arguments
[0], UNO_QUERY
);
239 xCollator
= lcl_loadDefaultCollator_throw( m_xContext
);
242 case 2: // SortableGridDataModel.createWithCollator( XMutableGridDataModel, XCollator )
243 xDelegator
.set( i_arguments
[0], UNO_QUERY
);
244 xCollator
.set( i_arguments
[1], UNO_QUERY
);
245 if ( !xCollator
.is() )
246 throw IllegalArgumentException( OUString(), *this, 2 );
249 if ( !xDelegator
.is() )
250 throw IllegalArgumentException( OUString(), *this, 1 );
252 m_delegator
= xDelegator
;
253 m_collator
= xCollator
;
255 m_delegator
->addGridDataListener( this );
257 m_isInitialized
= true;
260 //------------------------------------------------------------------------------------------------------------------
261 GridDataEvent
SortableGridDataModel::impl_createPublicEvent( GridDataEvent
const & i_originalEvent
) const
263 GridDataEvent
aEvent( i_originalEvent
);
264 aEvent
.Source
= *const_cast< SortableGridDataModel
* >( this );
265 aEvent
.FirstRow
= impl_getPublicRowIndex_nothrow( aEvent
.FirstRow
);
266 aEvent
.LastRow
= impl_getPublicRowIndex_nothrow( aEvent
.LastRow
);
270 //------------------------------------------------------------------------------------------------------------------
271 void SortableGridDataModel::impl_broadcast( void ( SAL_CALL
XGridDataListener::*i_listenerMethod
)( const GridDataEvent
& ),
272 GridDataEvent
const & i_publicEvent
, MethodGuard
& i_instanceLock
)
274 ::cppu::OInterfaceContainerHelper
* pListeners
= rBHelper
.getContainer( XGridDataListener::static_type() );
275 if ( pListeners
== NULL
)
278 i_instanceLock
.clear();
279 pListeners
->notifyEach( i_listenerMethod
, i_publicEvent
);
282 //------------------------------------------------------------------------------------------------------------------
283 void SAL_CALL
SortableGridDataModel::rowsInserted( const GridDataEvent
& i_event
) throw (RuntimeException
)
285 MethodGuard
aGuard( *this, rBHelper
);
288 if ( impl_isSorted_nothrow() )
290 // no infrastructure is in place currently to sort the new row to its proper location,
291 // so we remove the sorting here.
292 impl_removeColumnSort( aGuard
);
296 GridDataEvent
const aEvent( impl_createPublicEvent( i_event
) );
297 impl_broadcast( &XGridDataListener::rowsInserted
, aEvent
, aGuard
);
300 //------------------------------------------------------------------------------------------------------------------
303 void lcl_decrementValuesGreaterThan( ::std::vector
< ::sal_Int32
> & io_indexMap
, sal_Int32
const i_threshold
)
305 for ( ::std::vector
< ::sal_Int32
>::iterator loop
= io_indexMap
.begin();
306 loop
!= io_indexMap
.end();
310 if ( *loop
>= i_threshold
)
316 //------------------------------------------------------------------------------------------------------------------
317 void SortableGridDataModel::impl_rebuildIndexesAndNotify( MethodGuard
& i_instanceLock
)
319 OSL_PRECOND( impl_isSorted_nothrow(), "SortableGridDataModel::impl_rebuildIndexesAndNotify: illegal call!" );
322 lcl_clear( m_publicToPrivateRowIndex
);
323 lcl_clear( m_privateToPublicRowIndex
);
326 if ( !impl_reIndex_nothrow( m_currentSortColumn
, m_sortAscending
) )
328 impl_removeColumnSort( i_instanceLock
);
332 // broadcast an artificial event, saying that all rows have been removed
333 GridDataEvent
const aRemovalEvent( *this, -1, -1, -1, -1 );
334 impl_broadcast( &XGridDataListener::rowsRemoved
, aRemovalEvent
, i_instanceLock
);
335 i_instanceLock
.reset();
337 // broadcast an artificial event, saying that n rows have been added
338 GridDataEvent
const aAdditionEvent( *this, -1, -1, 0, m_delegator
->getRowCount() - 1 );
339 impl_broadcast( &XGridDataListener::rowsInserted
, aAdditionEvent
, i_instanceLock
);
342 //------------------------------------------------------------------------------------------------------------------
343 void SAL_CALL
SortableGridDataModel::rowsRemoved( const GridDataEvent
& i_event
) throw (RuntimeException
)
345 MethodGuard
aGuard( *this, rBHelper
);
348 // if the data is not sorted, broadcast the event unchanged
349 if ( !impl_isSorted_nothrow() )
351 GridDataEvent
const aEvent( impl_createPublicEvent( i_event
) );
352 impl_broadcast( &XGridDataListener::rowsRemoved
, aEvent
, aGuard
);
356 // if all rows have been removed, also simply multiplex to own listeners
357 if ( i_event
.FirstRow
< 0 )
359 lcl_clear( m_publicToPrivateRowIndex
);
360 lcl_clear( m_privateToPublicRowIndex
);
361 GridDataEvent
aEvent( i_event
);
362 aEvent
.Source
= *this;
363 impl_broadcast( &XGridDataListener::rowsRemoved
, aEvent
, aGuard
);
367 bool needReIndex
= false;
368 if ( i_event
.FirstRow
!= i_event
.LastRow
)
370 OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: missing implementation - removal of multiple rows!" );
373 else if ( size_t( i_event
.FirstRow
) >= m_privateToPublicRowIndex
.size() )
375 OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: inconsistent/wrong data!" );
381 impl_rebuildIndexesAndNotify( aGuard
);
385 // build public event version
386 GridDataEvent
const aEvent( impl_createPublicEvent( i_event
) );
388 // remove the entries from the index maps
389 sal_Int32
const privateIndex
= i_event
.FirstRow
;
390 sal_Int32
const publicIndex
= aEvent
.FirstRow
;
392 m_publicToPrivateRowIndex
.erase( m_publicToPrivateRowIndex
.begin() + publicIndex
);
393 m_privateToPublicRowIndex
.erase( m_privateToPublicRowIndex
.begin() + privateIndex
);
395 // adjust remaining entries in the index maps
396 lcl_decrementValuesGreaterThan( m_publicToPrivateRowIndex
, privateIndex
);
397 lcl_decrementValuesGreaterThan( m_privateToPublicRowIndex
, publicIndex
);
399 // broadcast the event
400 impl_broadcast( &XGridDataListener::rowsRemoved
, aEvent
, aGuard
);
403 //------------------------------------------------------------------------------------------------------------------
404 void SAL_CALL
SortableGridDataModel::dataChanged( const GridDataEvent
& i_event
) throw (RuntimeException
)
406 MethodGuard
aGuard( *this, rBHelper
);
409 GridDataEvent
const aEvent( impl_createPublicEvent( i_event
) );
410 impl_broadcast( &XGridDataListener::dataChanged
, aEvent
, aGuard
);
413 //------------------------------------------------------------------------------------------------------------------
414 void SAL_CALL
SortableGridDataModel::rowHeadingChanged( const GridDataEvent
& i_event
) throw (RuntimeException
)
416 MethodGuard
aGuard( *this, rBHelper
);
419 GridDataEvent
const aEvent( impl_createPublicEvent( i_event
) );
420 impl_broadcast( &XGridDataListener::rowHeadingChanged
, aEvent
, aGuard
);
423 //------------------------------------------------------------------------------------------------------------------
424 void SAL_CALL
SortableGridDataModel::disposing( const EventObject
& i_event
) throw (RuntimeException
)
427 OSL_UNUSED( i_event
);
430 //------------------------------------------------------------------------------------------------------------------
433 class CellDataLessComparison
: public ::std::binary_function
< sal_Int32
, sal_Int32
, bool >
436 CellDataLessComparison(
437 ::std::vector
< Any
> const & i_data
,
438 ::comphelper::IKeyPredicateLess
& i_predicate
,
439 sal_Bool
const i_sortAscending
442 ,m_predicate( i_predicate
)
443 ,m_sortAscending( i_sortAscending
)
447 bool operator()( sal_Int32
const i_lhs
, sal_Int32
const i_rhs
) const
449 Any
const & lhs
= m_data
[ i_lhs
];
450 Any
const & rhs
= m_data
[ i_rhs
];
451 // <VOID/> is less than everything else
452 if ( !lhs
.hasValue() )
453 return m_sortAscending
;
454 if ( !rhs
.hasValue() )
455 return !m_sortAscending
;
458 if ( m_sortAscending
)
459 return m_predicate
.isLess( lhs
, rhs
);
461 return m_predicate
.isLess( rhs
, lhs
);
465 ::std::vector
< Any
> const & m_data
;
466 ::comphelper::IKeyPredicateLess
const & m_predicate
;
467 sal_Bool
const m_sortAscending
;
471 //------------------------------------------------------------------------------------------------------------------
472 bool SortableGridDataModel::impl_reIndex_nothrow( ::sal_Int32
const i_columnIndex
, sal_Bool
const i_sortAscending
)
474 ::sal_Int32
const rowCount( getRowCount() );
475 ::std::vector
< ::sal_Int32
> aPublicToPrivate( rowCount
);
479 // build an unsorted translation table, and retrieve the unsorted data
480 ::std::vector
< Any
> aColumnData( rowCount
);
482 for ( ::sal_Int32 rowIndex
= 0; rowIndex
< rowCount
; ++rowIndex
)
484 aColumnData
[ rowIndex
] = m_delegator
->getCellData( i_columnIndex
, rowIndex
);
485 aPublicToPrivate
[ rowIndex
] = rowIndex
;
487 // determine the data types we assume for the complete column
488 if ( ( dataType
.getTypeClass() == TypeClass_VOID
) && aColumnData
[ rowIndex
].hasValue() )
489 dataType
= aColumnData
[ rowIndex
].getValueType();
492 // get predicate object
493 ::std::auto_ptr
< ::comphelper::IKeyPredicateLess
> const pPredicate( ::comphelper::getStandardLessPredicate( dataType
, m_collator
) );
494 ENSURE_OR_RETURN_FALSE( pPredicate
.get(), "SortableGridDataModel::impl_reIndex_nothrow: no sortable data found!" );
497 CellDataLessComparison
const aComparator( aColumnData
, *pPredicate
, i_sortAscending
);
498 ::std::sort( aPublicToPrivate
.begin(), aPublicToPrivate
.end(), aComparator
);
500 catch( const Exception
& )
502 DBG_UNHANDLED_EXCEPTION();
506 // also build the "private to public" mapping
507 ::std::vector
< sal_Int32
> aPrivateToPublic( aPublicToPrivate
.size() );
508 for ( size_t i
=0; i
<aPublicToPrivate
.size(); ++i
)
509 aPrivateToPublic
[ aPublicToPrivate
[i
] ] = i
;
511 m_publicToPrivateRowIndex
.swap( aPublicToPrivate
);
512 m_privateToPublicRowIndex
.swap( aPrivateToPublic
);
517 //------------------------------------------------------------------------------------------------------------------
518 void SAL_CALL
SortableGridDataModel::sortByColumn( ::sal_Int32 i_columnIndex
, ::sal_Bool i_sortAscending
) throw (IndexOutOfBoundsException
, RuntimeException
)
520 MethodGuard
aGuard( *this, rBHelper
);
523 if ( ( i_columnIndex
< 0 ) || ( i_columnIndex
>= getColumnCount() ) )
524 throw IndexOutOfBoundsException( OUString(), *this );
526 if ( !impl_reIndex_nothrow( i_columnIndex
, i_sortAscending
) )
529 m_currentSortColumn
= i_columnIndex
;
530 m_sortAscending
= i_sortAscending
;
533 &XGridDataListener::dataChanged
,
534 GridDataEvent( *this, -1, -1, -1, -1 ),
539 //------------------------------------------------------------------------------------------------------------------
540 void SortableGridDataModel::impl_removeColumnSort_noBroadcast()
542 lcl_clear( m_publicToPrivateRowIndex
);
543 lcl_clear( m_privateToPublicRowIndex
);
545 m_currentSortColumn
= -1;
546 m_sortAscending
= sal_True
;
549 //------------------------------------------------------------------------------------------------------------------
550 void SortableGridDataModel::impl_removeColumnSort( MethodGuard
& i_instanceLock
)
552 impl_removeColumnSort_noBroadcast();
554 &XGridDataListener::dataChanged
,
555 GridDataEvent( *this, -1, -1, -1, -1 ),
560 //------------------------------------------------------------------------------------------------------------------
561 void SAL_CALL
SortableGridDataModel::removeColumnSort( ) throw (RuntimeException
)
563 MethodGuard
aGuard( *this, rBHelper
);
565 impl_removeColumnSort( aGuard
);
568 //------------------------------------------------------------------------------------------------------------------
569 Pair
< ::sal_Int32
, ::sal_Bool
> SAL_CALL
SortableGridDataModel::getCurrentSortOrder( ) throw (RuntimeException
)
571 MethodGuard
aGuard( *this, rBHelper
);
574 return Pair
< ::sal_Int32
, ::sal_Bool
>( m_currentSortColumn
, m_sortAscending
);
577 //------------------------------------------------------------------------------------------------------------------
578 void SAL_CALL
SortableGridDataModel::addRow( const Any
& i_heading
, const Sequence
< Any
>& i_data
) throw (RuntimeException
)
580 MethodGuard
aGuard( *this, rBHelper
);
583 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
585 delegator
->addRow( i_heading
, i_data
);
588 //------------------------------------------------------------------------------------------------------------------
589 void SAL_CALL
SortableGridDataModel::addRows( const Sequence
< Any
>& i_headings
, const Sequence
< Sequence
< Any
> >& i_data
) throw (IllegalArgumentException
, RuntimeException
)
591 MethodGuard
aGuard( *this, rBHelper
);
594 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
596 delegator
->addRows( i_headings
, i_data
);
599 //------------------------------------------------------------------------------------------------------------------
600 void SAL_CALL
SortableGridDataModel::insertRow( ::sal_Int32 i_index
, const Any
& i_heading
, const Sequence
< Any
>& i_data
) throw (RuntimeException
, IndexOutOfBoundsException
)
602 MethodGuard
aGuard( *this, rBHelper
);
605 ::sal_Int32
const rowIndex
= i_index
== getRowCount() ? i_index
: impl_getPrivateRowIndex_throw( i_index
);
606 // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
608 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
610 delegator
->insertRow( rowIndex
, i_heading
, i_data
);
613 //------------------------------------------------------------------------------------------------------------------
614 void SAL_CALL
SortableGridDataModel::insertRows( ::sal_Int32 i_index
, const Sequence
< Any
>& i_headings
, const Sequence
< Sequence
< Any
> >& i_data
) throw (IllegalArgumentException
, IndexOutOfBoundsException
, RuntimeException
)
616 MethodGuard
aGuard( *this, rBHelper
);
619 ::sal_Int32
const rowIndex
= i_index
== getRowCount() ? i_index
: impl_getPrivateRowIndex_throw( i_index
);
620 // note that |RowCount| is a valid index in this method, but not for impl_getPrivateRowIndex_throw
622 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
624 delegator
->insertRows( rowIndex
, i_headings
, i_data
);
627 //------------------------------------------------------------------------------------------------------------------
628 void SAL_CALL
SortableGridDataModel::removeRow( ::sal_Int32 i_rowIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
630 MethodGuard
aGuard( *this, rBHelper
);
633 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
635 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
637 delegator
->removeRow( rowIndex
);
640 //------------------------------------------------------------------------------------------------------------------
641 void SAL_CALL
SortableGridDataModel::removeAllRows( ) throw (RuntimeException
)
643 MethodGuard
aGuard( *this, rBHelper
);
646 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
648 delegator
->removeAllRows();
651 //------------------------------------------------------------------------------------------------------------------
652 void SAL_CALL
SortableGridDataModel::updateCellData( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
, const Any
& i_value
) throw (IndexOutOfBoundsException
, RuntimeException
)
654 MethodGuard
aGuard( *this, rBHelper
);
657 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
659 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
661 delegator
->updateCellData( i_columnIndex
, rowIndex
, i_value
);
664 //------------------------------------------------------------------------------------------------------------------
665 void SAL_CALL
SortableGridDataModel::updateRowData( const Sequence
< ::sal_Int32
>& i_columnIndexes
, ::sal_Int32 i_rowIndex
, const Sequence
< Any
>& i_values
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
667 MethodGuard
aGuard( *this, rBHelper
);
670 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
672 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
674 delegator
->updateRowData( i_columnIndexes
, rowIndex
, i_values
);
677 //------------------------------------------------------------------------------------------------------------------
678 void SAL_CALL
SortableGridDataModel::updateRowHeading( ::sal_Int32 i_rowIndex
, const Any
& i_heading
) throw (IndexOutOfBoundsException
, RuntimeException
)
680 MethodGuard
aGuard( *this, rBHelper
);
683 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
685 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
687 delegator
->updateRowHeading( rowIndex
, i_heading
);
690 //------------------------------------------------------------------------------------------------------------------
691 void SAL_CALL
SortableGridDataModel::updateCellToolTip( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
, const Any
& i_value
) throw (IndexOutOfBoundsException
, RuntimeException
)
693 MethodGuard
aGuard( *this, rBHelper
);
696 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
698 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
700 delegator
->updateCellToolTip( i_columnIndex
, rowIndex
, i_value
);
703 //------------------------------------------------------------------------------------------------------------------
704 void SAL_CALL
SortableGridDataModel::updateRowToolTip( ::sal_Int32 i_rowIndex
, const Any
& i_value
) throw (IndexOutOfBoundsException
, RuntimeException
)
706 MethodGuard
aGuard( *this, rBHelper
);
709 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
711 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
713 delegator
->updateRowToolTip( rowIndex
, i_value
);
716 //------------------------------------------------------------------------------------------------------------------
717 void SAL_CALL
SortableGridDataModel::addGridDataListener( const Reference
< XGridDataListener
>& i_listener
) throw (RuntimeException
)
719 rBHelper
.addListener( XGridDataListener::static_type(), i_listener
);
722 //------------------------------------------------------------------------------------------------------------------
723 void SAL_CALL
SortableGridDataModel::removeGridDataListener( const Reference
< XGridDataListener
>& i_listener
) throw (RuntimeException
)
725 rBHelper
.removeListener( XGridDataListener::static_type(), i_listener
);
728 //------------------------------------------------------------------------------------------------------------------
729 ::sal_Int32 SAL_CALL
SortableGridDataModel::getRowCount() throw (RuntimeException
)
731 MethodGuard
aGuard( *this, rBHelper
);
734 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
736 return delegator
->getRowCount();
739 //------------------------------------------------------------------------------------------------------------------
740 ::sal_Int32 SAL_CALL
SortableGridDataModel::getColumnCount() throw (RuntimeException
)
742 MethodGuard
aGuard( *this, rBHelper
);
745 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
747 return delegator
->getColumnCount();
750 //------------------------------------------------------------------------------------------------------------------
751 Any SAL_CALL
SortableGridDataModel::getCellData( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
753 MethodGuard
aGuard( *this, rBHelper
);
756 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
758 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
760 return delegator
->getCellData( i_columnIndex
, rowIndex
);
763 //------------------------------------------------------------------------------------------------------------------
764 Any SAL_CALL
SortableGridDataModel::getCellToolTip( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
766 MethodGuard
aGuard( *this, rBHelper
);
769 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
771 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
773 return delegator
->getCellToolTip( i_columnIndex
, rowIndex
);
776 //------------------------------------------------------------------------------------------------------------------
777 Any SAL_CALL
SortableGridDataModel::getRowHeading( ::sal_Int32 i_rowIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
779 MethodGuard
aGuard( *this, rBHelper
);
782 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
784 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
786 return delegator
->getRowHeading( rowIndex
);
789 //------------------------------------------------------------------------------------------------------------------
790 Sequence
< Any
> SAL_CALL
SortableGridDataModel::getRowData( ::sal_Int32 i_rowIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
792 MethodGuard
aGuard( *this, rBHelper
);
795 ::sal_Int32
const rowIndex
= impl_getPrivateRowIndex_throw( i_rowIndex
);
797 Reference
< XMutableGridDataModel
> const delegator( m_delegator
);
799 return delegator
->getRowData( rowIndex
);
802 //------------------------------------------------------------------------------------------------------------------
803 void SAL_CALL
SortableGridDataModel::disposing()
805 m_currentSortColumn
= -1;
807 Reference
< XComponent
> const delegatorComponent( m_delegator
.get() );
808 m_delegator
->removeGridDataListener( this );
810 delegatorComponent
->dispose();
812 Reference
< XComponent
> const collatorComponent( m_collator
, UNO_QUERY
);
814 if ( collatorComponent
.is() )
815 collatorComponent
->dispose();
817 lcl_clear( m_publicToPrivateRowIndex
);
818 lcl_clear( m_privateToPublicRowIndex
);
821 //------------------------------------------------------------------------------------------------------------------
822 Reference
< XCloneable
> SAL_CALL
SortableGridDataModel::createClone( ) throw (RuntimeException
)
824 MethodGuard
aGuard( *this, rBHelper
);
827 return new SortableGridDataModel( *this );
830 //------------------------------------------------------------------------------------------------------------------
831 OUString SAL_CALL
SortableGridDataModel::getImplementationName( ) throw (RuntimeException
)
833 return OUString( "org.openoffice.comp.toolkit.SortableGridDataModel" );
836 //------------------------------------------------------------------------------------------------------------------
837 ::sal_Bool SAL_CALL
SortableGridDataModel::supportsService( const OUString
& i_serviceName
) throw (RuntimeException
)
839 Sequence
< OUString
> const aServiceNames( getSupportedServiceNames() );
840 for ( sal_Int32 i
=0; i
<aServiceNames
.getLength(); ++i
)
841 if ( aServiceNames
[i
] == i_serviceName
)
846 //------------------------------------------------------------------------------------------------------------------
847 Sequence
< OUString
> SAL_CALL
SortableGridDataModel::getSupportedServiceNames( ) throw (RuntimeException
)
849 Sequence
< OUString
> aServiceNames(1);
850 aServiceNames
[0] = OUString::createFromAscii( szServiceName_SortableGridDataModel
);
851 return aServiceNames
;
854 //------------------------------------------------------------------------------------------------------------------
855 ::sal_Int32
SortableGridDataModel::impl_getPrivateRowIndex_throw( ::sal_Int32
const i_publicRowIndex
) const
857 if ( ( i_publicRowIndex
< 0 ) || ( i_publicRowIndex
>= m_delegator
->getRowCount() ) )
858 throw IndexOutOfBoundsException( OUString(), *const_cast< SortableGridDataModel
* >( this ) );
860 if ( !impl_isSorted_nothrow() )
861 // no need to translate anything
862 return i_publicRowIndex
;
864 ENSURE_OR_RETURN( size_t( i_publicRowIndex
) < m_publicToPrivateRowIndex
.size(),
865 "SortableGridDataModel::impl_getPrivateRowIndex_throw: inconsistency!", i_publicRowIndex
);
866 // obviously the translation table contains too few elements - it should have exactly |getRowCount()|
869 return m_publicToPrivateRowIndex
[ i_publicRowIndex
];
872 //------------------------------------------------------------------------------------------------------------------
873 ::sal_Int32
SortableGridDataModel::impl_getPublicRowIndex_nothrow( ::sal_Int32
const i_privateRowIndex
) const
875 if ( !impl_isSorted_nothrow() )
876 // no need to translate anything
877 return i_privateRowIndex
;
879 if ( i_privateRowIndex
< 0 )
880 return i_privateRowIndex
;
882 ENSURE_OR_RETURN( size_t( i_privateRowIndex
) < m_privateToPublicRowIndex
.size(),
883 "SortableGridDataModel::impl_getPublicRowIndex_nothrow: invalid index!", i_privateRowIndex
);
885 return m_privateToPublicRowIndex
[ i_privateRowIndex
];
888 //......................................................................................................................
889 } // namespace toolkit
890 //......................................................................................................................
892 ::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
)
894 return *( new ::toolkit::SortableGridDataModel( comphelper::getComponentContext(i_factory
) ) );
897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */