diff options
author | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-18 11:49:20 +0100 |
---|---|---|
committer | Frank Schoenheit [fs] <frank.schoenheit@oracle.com> | 2011-01-18 11:49:20 +0100 |
commit | 961e924dbc7ebd1cea9927134524a443a7666240 (patch) | |
tree | 1ea8728c48000481196d1884308dc30c5867ce3a /toolkit | |
parent | e4e1fd5c1946b7ae2c774fc3e21dd2008efc5be9 (diff) |
gridsort: #163172# added UNO API support for sorting grid data. Implementation still unfinished.
Things missing in the SortableGridData implementation
- add as listener to the delegator, so we're notified of changes
- translate and multiplex those changes
- do own notifications (XGridDataListener.dataChanged) when the sort order changed
- (possibly) update the sort order when the data in the current sort-column changed
Diffstat (limited to 'toolkit')
-rw-r--r-- | toolkit/inc/toolkit/helper/servicenames.hxx | 1 | ||||
-rw-r--r-- | toolkit/source/controls/grid/gridcontrol.cxx | 32 | ||||
-rwxr-xr-x | toolkit/source/controls/grid/initguard.hxx | 64 | ||||
-rw-r--r-- | toolkit/source/controls/grid/makefile.mk | 5 | ||||
-rwxr-xr-x | toolkit/source/controls/grid/sortablegriddatamodel.cxx | 450 | ||||
-rwxr-xr-x | toolkit/source/controls/grid/sortablegriddatamodel.hxx | 138 | ||||
-rw-r--r-- | toolkit/source/helper/registerservices.cxx | 3 | ||||
-rw-r--r-- | toolkit/source/helper/servicenames.cxx | 2 | ||||
-rw-r--r-- | toolkit/util/tk.component | 3 |
9 files changed, 688 insertions, 10 deletions
diff --git a/toolkit/inc/toolkit/helper/servicenames.hxx b/toolkit/inc/toolkit/helper/servicenames.hxx index 2d1df79b733b..a149f9e8f25f 100644 --- a/toolkit/inc/toolkit/helper/servicenames.hxx +++ b/toolkit/inc/toolkit/helper/servicenames.hxx @@ -97,6 +97,7 @@ extern const sal_Char __FAR_DATA szServiceName_GridControlModel[]; extern const sal_Char __FAR_DATA szServiceName_DefaultGridDataModel[]; extern const sal_Char __FAR_DATA szServiceName_DefaultGridColumnModel[]; extern const sal_Char __FAR_DATA szServiceName_GridColumn[]; +extern const sal_Char __FAR_DATA szServiceName_SortableGridDataModel[]; extern const sal_Char __FAR_DATA szServiceName_UnoSimpleAnimationControl[], szServiceName2_UnoSimpleAnimationControl[]; extern const sal_Char __FAR_DATA szServiceName_UnoSimpleAnimationControlModel[], szServiceName2_UnoSimpleAnimationControlModel[]; diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx index 14faa851400a..f054ca1ea05d 100644 --- a/toolkit/source/controls/grid/gridcontrol.cxx +++ b/toolkit/source/controls/grid/gridcontrol.cxx @@ -35,6 +35,8 @@ #include <com/sun/star/view/SelectionType.hpp> #include <com/sun/star/awt/grid/XGridDataModel.hpp> #include <com/sun/star/awt/grid/XMutableGridDataModel.hpp> +#include <com/sun/star/awt/grid/DefaultGridDataModel.hpp> +#include <com/sun/star/awt/grid/SortableGridDataModel.hpp> #include <com/sun/star/awt/grid/XGridColumnModel.hpp> #include <toolkit/helper/unopropertyarrayhelper.hxx> #include <toolkit/helper/property.hxx> @@ -55,9 +57,25 @@ using namespace ::com::sun::star::view; namespace toolkit { -// ---------------------------------------------------- -// class UnoGridModel -// ---------------------------------------------------- +//====================================================================================================================== +//= UnoGridModel +//====================================================================================================================== +namespace +{ + Reference< XGridDataModel > lcl_getDefaultDataModel_throw( ::comphelper::ComponentContext const & i_context ) + { + Reference< XMutableGridDataModel > const xDelegatorModel( DefaultGridDataModel::create( i_context.getUNOContext() ), UNO_QUERY_THROW ); + Reference< XGridDataModel > const xDataModel( SortableGridDataModel::create( i_context.getUNOContext(), xDelegatorModel ), UNO_QUERY_THROW ); + return xDataModel; + } + + Reference< XGridColumnModel > lcl_getDefaultColumnModel_throw( ::comphelper::ComponentContext const & i_context ) + { + Reference< XGridColumnModel > const xColumnModel( i_context.createComponent( "com.sun.star.awt.grid.DefaultGridColumnModel" ), UNO_QUERY_THROW ); + return xColumnModel; + } +} + //---------------------------------------------------------------------------------------------------------------------- UnoGridModel::UnoGridModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) :UnoControlModel( i_factory ) @@ -80,8 +98,8 @@ UnoGridModel::UnoGridModel( const ::com::sun::star::uno::Reference< ::com::sun:: ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER ); ImplRegisterProperty( BASEPROPERTY_COLUMN_HEADER_HEIGHT ); ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT ); - ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL, makeAny( maContext.createComponent( "com.sun.star.awt.grid.DefaultGridDataModel" ) ) ); - ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( maContext.createComponent( "com.sun.star.awt.grid.DefaultGridColumnModel" ) ) ); + ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL, makeAny( lcl_getDefaultDataModel_throw( maContext ) ) ); + ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( lcl_getDefaultColumnModel_throw( maContext ) ) ); ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE ); ImplRegisterProperty( BASEPROPERTY_FONTRELIEF ); ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK ); @@ -114,7 +132,7 @@ UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) DBG_UNHANDLED_EXCEPTION(); } if ( !success ) - setFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL, makeAny( maContext.createComponent( "com.sun.star.awt.grid.DefaultGridDataModel" ) ) ); + setFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL, makeAny( lcl_getDefaultDataModel_throw( maContext ) ) ); // clone the column model success = false; @@ -129,7 +147,7 @@ UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) DBG_UNHANDLED_EXCEPTION(); } if ( !success ) - setFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( maContext.createComponent( "com.sun.star.awt.grid.DefaultGridColumnModel" ) ) ); + setFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( lcl_getDefaultColumnModel_throw( maContext ) ) ); } //---------------------------------------------------------------------------------------------------------------------- diff --git a/toolkit/source/controls/grid/initguard.hxx b/toolkit/source/controls/grid/initguard.hxx new file mode 100755 index 000000000000..b2dddd2e5987 --- /dev/null +++ b/toolkit/source/controls/grid/initguard.hxx @@ -0,0 +1,64 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SVTOOLS_INITGUARD_HXX +#define SVTOOLS_INITGUARD_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/NotInitializedException.hpp> +/** === end UNO includes === **/ + +#include <comphelper/componentguard.hxx> + +//...................................................................................................................... +namespace toolkit +{ +//...................................................................................................................... + + //================================================================================================================== + //= InitGuard + //================================================================================================================== + template < class IMPL > + class InitGuard : public ::comphelper::ComponentGuard + { + public: + InitGuard( IMPL& i_component, ::cppu::OBroadcastHelper & i_broadcastHelper ) + :comphelper::ComponentGuard( i_component, i_broadcastHelper ) + { + if ( !i_component.isInitialized() ) + throw ::com::sun::star::lang::NotInitializedException( ::rtl::OUString(), *&i_component ); + } + + ~InitGuard() + { + } + }; + +//...................................................................................................................... +} // namespace toolkit +//...................................................................................................................... + +#endif // SVTOOLS_INITGUARD_HXX diff --git a/toolkit/source/controls/grid/makefile.mk b/toolkit/source/controls/grid/makefile.mk index c7bc6f038b10..5b4e87bf77ee 100644 --- a/toolkit/source/controls/grid/makefile.mk +++ b/toolkit/source/controls/grid/makefile.mk @@ -44,8 +44,9 @@ SLOFILES= \ $(SLO)$/defaultgriddatamodel.obj\ $(SLO)$/defaultgridcolumnmodel.obj\ $(SLO)$/gridcolumn.obj\ - $(SLO)$/grideventforwarder.obj - + $(SLO)$/grideventforwarder.obj\ + $(SLO)$/sortablegriddatamodel.obj + # --- Targets ------------------------------------------------------ .INCLUDE : target.mk diff --git a/toolkit/source/controls/grid/sortablegriddatamodel.cxx b/toolkit/source/controls/grid/sortablegriddatamodel.cxx new file mode 100755 index 000000000000..4b525dbc925a --- /dev/null +++ b/toolkit/source/controls/grid/sortablegriddatamodel.cxx @@ -0,0 +1,450 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_toolkit.hxx" + +#include "sortablegriddatamodel.hxx" +#include "initguard.hxx" +#include "toolkit/helper/servicenames.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/i18n/XCollator.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +/** === end UNO includes === **/ + +#include <comphelper/anycompare.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/svapp.hxx> + +//...................................................................................................................... +namespace toolkit +{ +//...................................................................................................................... + + /** === begin UNO using === **/ + using ::com::sun::star::uno::TypeClass; + using ::com::sun::star::uno::TypeClass_VOID; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::uno::Any; + using ::com::sun::star::uno::makeAny; + using ::com::sun::star::uno::Sequence; + using ::com::sun::star::uno::Type; + using ::com::sun::star::lang::IndexOutOfBoundsException; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::awt::grid::XGridDataListener; + using ::com::sun::star::beans::Pair; + using ::com::sun::star::util::XCloneable; + using ::com::sun::star::i18n::XCollator; + using ::com::sun::star::lang::IllegalArgumentException; + using ::com::sun::star::lang::XMultiServiceFactory; + /** === end UNO using === **/ + + typedef InitGuard< SortableGridDataModel > MethodGuard; + + //================================================================================================================== + //= SortableGridDataModel + //================================================================================================================== + //------------------------------------------------------------------------------------------------------------------ + SortableGridDataModel::SortableGridDataModel( Reference< XMultiServiceFactory > const & i_factory ) + :SortableGridDataModel_Base( m_aMutex ) + ,m_context( i_factory ) + ,m_isInitialized( false ) + ,m_delegator() + ,m_collator() + ,m_currentSortColumn( -1 ) + ,m_sortAscending( true ) + ,m_rowIndexTranslation() + { + } + + //------------------------------------------------------------------------------------------------------------------ + SortableGridDataModel::SortableGridDataModel( SortableGridDataModel const & i_copySource ) + :cppu::BaseMutex() + ,SortableGridDataModel_Base( m_aMutex ) + ,m_context( i_copySource.m_context ) + ,m_collator( i_copySource.m_collator ) + ,m_isInitialized( true ) + ,m_delegator() + ,m_currentSortColumn( i_copySource.m_currentSortColumn ) + ,m_sortAscending( i_copySource.m_sortAscending ) + ,m_rowIndexTranslation( i_copySource.m_rowIndexTranslation ) + { + ENSURE_OR_THROW( i_copySource.m_delegator.is(), + "not expected to be called for a disposed copy source!" ); + m_delegator.set( i_copySource.m_delegator->createClone(), UNO_QUERY_THROW ); + } + + //------------------------------------------------------------------------------------------------------------------ + SortableGridDataModel::~SortableGridDataModel() + { + if ( !rBHelper.bDisposed ) + { + acquire(); + dispose(); + } + } + + //------------------------------------------------------------------------------------------------------------------ + namespace + { + Reference< XCollator > lcl_loadDefaultCollator_throw( ::comphelper::ComponentContext const & i_context ) + { + Reference< XCollator > const xCollator( i_context.createComponent( "com.sun.star.i18n.Collator" ), UNO_QUERY_THROW ); + xCollator->loadDefaultCollator( Application::GetSettings().GetLocale(), 0 ); + return xCollator; + } + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::initialize( const Sequence< Any >& i_arguments ) throw (Exception, RuntimeException) + { + ::comphelper::ComponentGuard aGuard( *this, rBHelper ); + + Reference< XMutableGridDataModel > xDelegator; + Reference< XCollator > xCollator; + switch ( i_arguments.getLength() ) + { + case 1: // SortableGridDataModel.create( XMutableGridDataModel ) + xDelegator.set( i_arguments[0], UNO_QUERY ); + xCollator = lcl_loadDefaultCollator_throw( m_context ); + break; + + case 2: // SortableGridDataModel.createWithCollator( XMutableGridDataModel, XCollator ) + xDelegator.set( i_arguments[0], UNO_QUERY ); + xCollator.set( i_arguments[1], UNO_QUERY ); + if ( !xCollator.is() ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 2 ); + break; + } + if ( !xDelegator.is() ) + throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); + + // TODO: add as listener to the delegator model, so we're able to multiplex the events it will notify + + m_delegator = xDelegator; + m_isInitialized = true; + } + + //------------------------------------------------------------------------------------------------------------------ + namespace + { + class CellDataLessComparison : public ::std::binary_function< sal_Int32, sal_Int32, bool > + { + public: + CellDataLessComparison( + ::std::vector< Any > const & i_data, + ::comphelper::IKeyPredicateLess& i_predicate, + sal_Bool const i_sortAscending + ) + :m_data( i_data ) + ,m_predicate( i_predicate ) + ,m_sortAscending( i_sortAscending ) + { + } + + bool operator()( sal_Int32 const i_lhs, sal_Int32 const i_rhs ) const + { + Any const & lhs = m_data[ i_lhs ]; + Any const & rhs = m_data[ i_rhs ]; + // <VOID/> is less than everything else + if ( !lhs.hasValue() ) + return m_sortAscending; + if ( !rhs.hasValue() ) + return !m_sortAscending; + + // actually compare + if ( m_sortAscending ) + return m_predicate.isLess( lhs, rhs ); + else + return m_predicate.isLess( rhs, lhs ); + } + + private: + ::std::vector< Any > const & m_data; + ::comphelper::IKeyPredicateLess const & m_predicate; + sal_Bool const m_sortAscending; + }; + } + + //------------------------------------------------------------------------------------------------------------------ + void SortableGridDataModel::impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending ) + { + ::sal_Int32 const rowCount( getRowCount() ); + ::std::vector< ::sal_Int32 > aIndexTranslation( rowCount ); + + try + { + // build an unsorted translation table, and retrieve the unsorted data + ::std::vector< Any > aColumnData( rowCount ); + Type dataType; + for ( ::sal_Int32 rowIndex = 0; rowIndex < rowCount; ++rowIndex ) + { + aColumnData[ rowIndex ] = m_delegator->getCellData( i_columnIndex, rowIndex ); + aIndexTranslation[ rowIndex ] = rowIndex; + + // determine the data types we assume for the complete column + if ( ( dataType.getTypeClass() == TypeClass_VOID ) && aColumnData[ rowIndex ].hasValue() ) + dataType = aColumnData[ rowIndex ].getValueType(); + } + + // get predicate object + ::std::auto_ptr< ::comphelper::IKeyPredicateLess > const pPredicate( ::comphelper::getStandardLessPredicate( dataType ) ); + ENSURE_OR_RETURN_VOID( pPredicate.get(), "SortableGridDataModel::impl_reIndex_nothrow: no sortable data found!" ); + + // then sort + CellDataLessComparison const aComparator( aColumnData, *pPredicate, i_sortAscending ); + ::std::sort( aIndexTranslation.begin(), aIndexTranslation.end(), aComparator ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + return; + } + + m_rowIndexTranslation.swap( aIndexTranslation ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::sortByColumn( ::sal_Int32 i_columnIndex, ::sal_Bool i_sortAscending ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + + if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= getColumnCount() ) ) + throw IndexOutOfBoundsException( ::rtl::OUString(), *this ); + + impl_reIndex_nothrow( i_columnIndex, i_sortAscending ); + + m_currentSortColumn = i_columnIndex; + m_sortAscending = i_sortAscending; + } + + //------------------------------------------------------------------------------------------------------------------ + Pair< ::sal_Int32, ::sal_Bool > SAL_CALL SortableGridDataModel::getCurrentSortOrder( ) throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + return Pair< ::sal_Int32, ::sal_Bool >( m_currentSortColumn, m_sortAscending ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::addRow( const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + m_delegator->addRow( i_heading, i_data ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::addRows( const Sequence< Any >& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + m_delegator->addRows( i_headings, i_data ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::removeRow( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->removeRow( rowIndex ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::removeAllRows( ) throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + m_delegator->removeAllRows(); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::updateCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->updateCellData( i_columnIndex, rowIndex, i_value ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::updateRowData( const Sequence< ::sal_Int32 >& i_columnIndexes, ::sal_Int32 i_rowIndex, const Sequence< Any >& i_values ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->updateRowData( i_columnIndexes, rowIndex, i_values ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::setRowHeading( ::sal_Int32 i_rowIndex, const Any& i_heading ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->setRowHeading( rowIndex, i_heading ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::updateCellToolTip( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->updateCellToolTip( i_columnIndex, rowIndex, i_value ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::updateRowToolTip( ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + m_delegator->updateRowToolTip( rowIndex, i_value ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::addGridDataListener( const Reference< XGridDataListener >& i_listener ) throw (RuntimeException) + { + rBHelper.addListener( XGridDataListener::static_type(), i_listener ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::removeGridDataListener( const Reference< XGridDataListener >& i_listener ) throw (RuntimeException) + { + rBHelper.removeListener( XGridDataListener::static_type(), i_listener ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Int32 SAL_CALL SortableGridDataModel::getRowCount() throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + return m_delegator->getRowCount(); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Int32 SAL_CALL SortableGridDataModel::getColumnCount() throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + return m_delegator->getColumnCount(); + } + + //------------------------------------------------------------------------------------------------------------------ + Any SAL_CALL SortableGridDataModel::getCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + return m_delegator->getCellData( i_columnIndex, rowIndex ); + } + + //------------------------------------------------------------------------------------------------------------------ + Any SAL_CALL SortableGridDataModel::getCellToolTip( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + return m_delegator->getCellToolTip( i_columnIndex, rowIndex ); + } + + //------------------------------------------------------------------------------------------------------------------ + Any SAL_CALL SortableGridDataModel::getRowHeading( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + ::sal_Int32 const rowIndex = impl_translateRowIndex_throw( i_rowIndex ); + return m_delegator->getRowHeading( rowIndex ); + } + + //------------------------------------------------------------------------------------------------------------------ + void SAL_CALL SortableGridDataModel::disposing() + { + m_currentSortColumn = -1; + + Reference< XComponent > const delegatorComponent( m_delegator.get() ); + m_delegator.clear(); + delegatorComponent->dispose(); + + Reference< XComponent > const collatorComponent( m_collator, UNO_QUERY ); + m_collator.clear(); + if ( collatorComponent.is() ) + collatorComponent->dispose(); + + ::std::vector< ::sal_Int32 > aEmpty; + m_rowIndexTranslation.swap( aEmpty ); + } + + //------------------------------------------------------------------------------------------------------------------ + Reference< XCloneable > SAL_CALL SortableGridDataModel::createClone( ) throw (RuntimeException) + { + MethodGuard aGuard( *this, rBHelper ); + return new SortableGridDataModel( *this ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::rtl::OUString SAL_CALL SortableGridDataModel::getImplementationName( ) throw (RuntimeException) + { + return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.toolkit.SortableGridDataModel" ) ); + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Bool SAL_CALL SortableGridDataModel::supportsService( const ::rtl::OUString& i_serviceName ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > const aServiceNames( getSupportedServiceNames() ); + for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i ) + if ( aServiceNames[i] == i_serviceName ) + return sal_True; + return sal_False; + } + + //------------------------------------------------------------------------------------------------------------------ + Sequence< ::rtl::OUString > SAL_CALL SortableGridDataModel::getSupportedServiceNames( ) throw (RuntimeException) + { + Sequence< ::rtl::OUString > aServiceNames(1); + aServiceNames[0] = ::rtl::OUString::createFromAscii( szServiceName_SortableGridDataModel ); + return aServiceNames; + } + + //------------------------------------------------------------------------------------------------------------------ + ::sal_Int32 SortableGridDataModel::impl_translateRowIndex_throw( ::sal_Int32 const i_publicRowIndex ) const + { + if ( ( i_publicRowIndex < 0 ) || ( i_publicRowIndex >= m_delegator->getRowCount() ) ) + throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SortableGridDataModel* >( this ) ); + + if ( !impl_isSorted_nothrow() ) + // no need to translate anything + return i_publicRowIndex; + + ENSURE_OR_RETURN( size_t( i_publicRowIndex ) < m_rowIndexTranslation.size(), + "SortableGridDataModel::impl_translateRowIndex_throw: inconsistency!", i_publicRowIndex ); + // obviously the translation table contains too few elements - it should have exactly |getRowCount()| + // elements + + return m_rowIndexTranslation[ i_publicRowIndex ]; + } + +//...................................................................................................................... +} // namespace toolkit +//...................................................................................................................... + +::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 ) +{ + return *( new ::toolkit::SortableGridDataModel( i_factory ) ); +} diff --git a/toolkit/source/controls/grid/sortablegriddatamodel.hxx b/toolkit/source/controls/grid/sortablegriddatamodel.hxx new file mode 100755 index 000000000000..64dad34af2bf --- /dev/null +++ b/toolkit/source/controls/grid/sortablegriddatamodel.hxx @@ -0,0 +1,138 @@ +/************************************************************************* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef TOOLKIT_SORTABLEGRIDDATAMODEL_HXX +#define TOOLKIT_SORTABLEGRIDDATAMODEL_HXX + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/grid/XSortableMutableGridDataModel.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/i18n/XCollator.hpp> +/** === end UNO includes === **/ + +#include <comphelper/componentcontext.hxx> +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/compbase3.hxx> + +//...................................................................................................................... +namespace toolkit +{ +//...................................................................................................................... + + //================================================================================================================== + //= SortableGridDataModel + //================================================================================================================== + typedef ::cppu::WeakComponentImplHelper3 < ::com::sun::star::awt::grid::XSortableMutableGridDataModel + , ::com::sun::star::lang::XServiceInfo + , ::com::sun::star::lang::XInitialization + > SortableGridDataModel_Base; + class SortableGridDataModel :public ::cppu::BaseMutex + ,public SortableGridDataModel_Base + { + public: + SortableGridDataModel( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > const & i_factory ); + SortableGridDataModel( SortableGridDataModel const & i_copySource ); + + public: + bool isInitialized() const { return m_isInitialized; } + + protected: + ~SortableGridDataModel(); + + public: + // XSortableGridData + virtual void SAL_CALL sortByColumn( ::sal_Int32 ColumnIndex, ::sal_Bool SortAscending ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::Pair< ::sal_Int32, ::sal_Bool > SAL_CALL getCurrentSortOrder( ) throw (::com::sun::star::uno::RuntimeException); + + // XMutableGridDataModel + virtual void SAL_CALL addRow( const ::com::sun::star::uno::Any& Heading, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Data ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addRows( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Headings, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& Data ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeRow( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeAllRows( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateCellData( ::sal_Int32 ColumnIndex, ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRowData( const ::com::sun::star::uno::Sequence< ::sal_Int32 >& ColumnIndexes, ::sal_Int32 RowIndex, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& Values ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setRowHeading( ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Heading ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateCellToolTip( ::sal_Int32 ColumnIndex, ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL updateRowToolTip( ::sal_Int32 RowIndex, const ::com::sun::star::uno::Any& Value ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addGridDataListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removeGridDataListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridDataListener >& Listener ) throw (::com::sun::star::uno::RuntimeException); + + // XGridDataModel + virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getCellData( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getCellToolTip( ::sal_Int32 Column, ::sal_Int32 Row ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getRowHeading( ::sal_Int32 RowIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + // OComponentHelper + virtual void SAL_CALL disposing(); + + // XCloneable + virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + private: + /** translates the given public index into one to be passed to our delegator + @throws ::com::sun::star::lang::IndexOutOfBoundsException + if the given index does not denote a valid row + */ + ::sal_Int32 impl_translateRowIndex_throw( ::sal_Int32 const i_publicRowIndex ) const; + + inline bool impl_isSorted_nothrow() const + { + return m_currentSortColumn >= 0; + } + + /** rebuilds the index translation structure. + + Neither <member>m_currentSortColumn</member> nor <member>m_sortAscending</member> are touched by this method. + Also, the given column index is not checked, this is the responsibility of the caller. + */ + void impl_reIndex_nothrow( ::sal_Int32 const i_columnIndex, sal_Bool const i_sortAscending ); + + private: + ::comphelper::ComponentContext m_context; + bool m_isInitialized; + ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XMutableGridDataModel > m_delegator; + ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCollator > m_collator; + ::sal_Int32 m_currentSortColumn; + ::sal_Bool m_sortAscending; + ::std::vector< ::sal_Int32 > m_rowIndexTranslation; + }; + +//...................................................................................................................... +} // namespace toolkit +//...................................................................................................................... + +#endif // TOOLKIT_SORTABLEGRIDDATAMODEL_HXX diff --git a/toolkit/source/helper/registerservices.cxx b/toolkit/source/helper/registerservices.cxx index ef6dca4f4916..61e734d39208 100644 --- a/toolkit/source/helper/registerservices.cxx +++ b/toolkit/source/helper/registerservices.cxx @@ -207,6 +207,7 @@ extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL DefaultGridDataModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); extern ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL GridColumn_CreateInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ); +extern ::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 >& ); extern void * SAL_CALL comp_AsyncCallback_component_getFactory( const char * implName, void * serviceManager, void * registryKey ); @@ -298,7 +299,7 @@ TOOLKIT_DLLPUBLIC void* SAL_CALL component_getFactory( const sal_Char* sImplemen GET_FACTORY( DefaultGridDataModel, szServiceName_DefaultGridDataModel, NULL ); GET_FACTORY( DefaultGridColumnModel, szServiceName_DefaultGridColumnModel, NULL ); GET_FACTORY_WITH_IMPL_PREFIX( GridColumn, "org.openoffice.comp.toolkit", szServiceName_GridColumn, NULL ); - + GET_FACTORY_WITH_IMPL_PREFIX( SortableGridDataModel, "org.openoffice.comp.toolkit", szServiceName_SortableGridDataModel, NULL ); if ( rtl_str_compare( sImplementationName, "com.sun.star.awt.comp.AsyncCallback" ) == 0 ) return comp_AsyncCallback_component_getFactory( sImplementationName, _pServiceManager, _pRegistryKey ); diff --git a/toolkit/source/helper/servicenames.cxx b/toolkit/source/helper/servicenames.cxx index f57f52f13e57..0a2131a92eb3 100644 --- a/toolkit/source/helper/servicenames.cxx +++ b/toolkit/source/helper/servicenames.cxx @@ -102,3 +102,5 @@ const sal_Char __FAR_DATA szServiceName_GridControlModel[] = "com.sun.star.awt.g const sal_Char __FAR_DATA szServiceName_DefaultGridDataModel[] = "com.sun.star.awt.grid.DefaultGridDataModel"; const sal_Char __FAR_DATA szServiceName_DefaultGridColumnModel[] = "com.sun.star.awt.grid.DefaultGridColumnModel"; const sal_Char __FAR_DATA szServiceName_GridColumn[] = "com.sun.star.awt.grid.GridColumn"; +const sal_Char __FAR_DATA szServiceName_SortableGridDataModel[] = "com.sun.star.awt.grid.SortableGridDataModel"; + diff --git a/toolkit/util/tk.component b/toolkit/util/tk.component index e919e8451dbb..ef6e8abfc268 100644 --- a/toolkit/util/tk.component +++ b/toolkit/util/tk.component @@ -44,6 +44,9 @@ <implementation name="org.openoffice.comp.toolkit.GridColumn"> <service name="com.sun.star.awt.grid.GridColumn"/> </implementation> + <implementation name="org.openoffice.comp.toolkit.SortableGridDataModel"> + <service name="com.sun.star.awt.grid.SortableGridDataModel"/> + </implementation> <implementation name="stardiv.Toolkit.GridControl"> <service name="com.sun.star.awt.grid.UnoControlGrid"/> </implementation> |