summaryrefslogtreecommitdiff
path: root/toolkit/source/controls/grid
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/source/controls/grid')
-rw-r--r--toolkit/source/controls/grid/defaultgridcolumnmodel.cxx460
-rw-r--r--toolkit/source/controls/grid/defaultgridcolumnmodel.hxx81
-rw-r--r--toolkit/source/controls/grid/defaultgriddatamodel.cxx567
-rw-r--r--toolkit/source/controls/grid/defaultgriddatamodel.hxx99
-rw-r--r--toolkit/source/controls/grid/gridcolumn.cxx480
-rw-r--r--toolkit/source/controls/grid/gridcolumn.hxx114
-rw-r--r--toolkit/source/controls/grid/gridcontrol.cxx313
-rw-r--r--toolkit/source/controls/grid/gridcontrol.hxx55
-rwxr-xr-xtoolkit/source/controls/grid/grideventforwarder.cxx149
-rwxr-xr-xtoolkit/source/controls/grid/grideventforwarder.hxx85
-rwxr-xr-xtoolkit/source/controls/grid/initguard.hxx64
-rwxr-xr-xtoolkit/source/controls/grid/sortablegriddatamodel.cxx877
-rwxr-xr-xtoolkit/source/controls/grid/sortablegriddatamodel.hxx198
13 files changed, 2723 insertions, 819 deletions
diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx
index 011f3502cdd8..0195ddff09a2 100644
--- a/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx
+++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.cxx
@@ -27,174 +27,366 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
+
#include "defaultgridcolumnmodel.hxx"
-#include <comphelper/sequence.hxx>
-#include <toolkit/helper/servicenames.hxx>
+#include "gridcolumn.hxx"
+
+/** === begin UNO includes === **/
#include <com/sun/star/awt/XVclWindowPeer.hpp>
-#include <rtl/ref.hxx>
+/** === end UNO includes === **/
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::style;
+#include <comphelper/sequence.hxx>
+#include <comphelper/componentguard.hxx>
+#include <toolkit/helper/servicenames.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/diagnose_ex.h>
+//......................................................................................................................
namespace toolkit
+//......................................................................................................................
{
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::awt::grid::XGridColumn;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::lang::XMultiServiceFactory;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::container::XContainerListener;
+ using ::com::sun::star::container::ContainerEvent;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::lang::IndexOutOfBoundsException;
+ using ::com::sun::star::util::XCloneable;
+ using ::com::sun::star::lang::IllegalArgumentException;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= DefaultGridColumnModel
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridColumnModel::DefaultGridColumnModel( const Reference< XMultiServiceFactory >& i_factory )
+ :DefaultGridColumnModel_Base( m_aMutex )
+ ,m_aContext( i_factory )
+ ,m_aContainerListeners( m_aMutex )
+ ,m_aColumns()
+ {
+ }
-///////////////////////////////////////////////////////////////////////
-// class DefaultGridColumnModel
-///////////////////////////////////////////////////////////////////////
-
-DefaultGridColumnModel::DefaultGridColumnModel(const Reference< XMultiServiceFactory >& xFactory)
-: columns(std::vector< Reference< XGridColumn > >())
- ,m_nColumnHeaderHeight(0)
- ,m_xFactory(xFactory)
-{
-}
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridColumnModel::DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource )
+ :cppu::BaseMutex()
+ ,DefaultGridColumnModel_Base( m_aMutex )
+ ,m_aContext( i_copySource.m_aContext )
+ ,m_aContainerListeners( m_aMutex )
+ ,m_aColumns()
+ {
+ Columns aColumns;
+ aColumns.reserve( i_copySource.m_aColumns.size() );
+ try
+ {
+ for ( Columns::const_iterator col = i_copySource.m_aColumns.begin();
+ col != i_copySource.m_aColumns.end();
+ ++col
+ )
+ {
+ Reference< XCloneable > const xCloneable( *col, UNO_QUERY_THROW );
+ Reference< XGridColumn > const xClone( xCloneable->createClone(), UNO_QUERY_THROW );
+
+ GridColumn* const pGridColumn = GridColumn::getImplementation( xClone );
+ if ( pGridColumn == NULL )
+ throw RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid clone source implementation" ) ), *this );
+ // that's indeed a RuntimeException, not an IllegalArgumentException or some such:
+ // a DefaultGridColumnModel implementation whose columns are not GridColumn implementations
+ // is borked.
+ pGridColumn->setIndex( col - i_copySource.m_aColumns.begin() );
+
+ aColumns.push_back( xClone );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ if ( aColumns.size() == i_copySource.m_aColumns.size() )
+ m_aColumns.swap( aColumns );
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridColumnModel::~DefaultGridColumnModel()
+ {
+ }
-DefaultGridColumnModel::~DefaultGridColumnModel()
-{
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (RuntimeException)
+ {
+ return m_aColumns.size();
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::createColumn( ) throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return new GridColumn();
+ }
-::sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnCount() throw (::com::sun::star::uno::RuntimeException)
-{
- return columns.size();
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn( const Reference< XGridColumn > & i_column ) throw (RuntimeException, IllegalArgumentException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-//---------------------------------------------------------------------
+ GridColumn* const pGridColumn = GridColumn::getImplementation( i_column );
+ if ( pGridColumn == NULL )
+ throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "invalid column implementation" ) ), *this, 1 );
-::sal_Int32 SAL_CALL DefaultGridColumnModel::addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- Reference<XGridColumn> xColumn(column);
- columns.push_back(xColumn);
- sal_Int32 index = columns.size() - 1;
- xColumn->setIndex(index);
- return index;
-}
+ m_aColumns.push_back( i_column );
+ sal_Int32 index = m_aColumns.size() - 1;
+ pGridColumn->setIndex( index );
-//---------------------------------------------------------------------
+ // fire insertion notifications
+ ContainerEvent aEvent;
+ aEvent.Source = *this;
+ aEvent.Accessor <<= index;
+ aEvent.Element <<= i_column;
-::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (::com::sun::star::uno::RuntimeException)
-{
- return comphelper::containerToSequence(columns);
-}
+ aGuard.clear();
+ m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvent );
-//---------------------------------------------------------------------
+ return index;
+ }
-::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
-{
- if ( index >=0 && index < ((sal_Int32)columns.size()))
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridColumnModel::removeColumn( ::sal_Int32 i_columnIndex ) throw (RuntimeException, IndexOutOfBoundsException)
{
- return columns[index];
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+
+ if ( ( i_columnIndex < 0 ) || ( size_t( i_columnIndex ) >= m_aColumns.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
+
+ Columns::iterator const pos = m_aColumns.begin() + i_columnIndex;
+ Reference< XGridColumn > const xColumn( *pos );
+ m_aColumns.erase( pos );
+
+ // update indexes of all subsequent columns
+ sal_Int32 columnIndex( i_columnIndex );
+ for ( Columns::iterator updatePos = m_aColumns.begin() + columnIndex;
+ updatePos != m_aColumns.end();
+ ++updatePos, ++columnIndex
+ )
+ {
+ GridColumn* pColumnImpl = GridColumn::getImplementation( *updatePos );
+ ENSURE_OR_CONTINUE( pColumnImpl, "DefaultGridColumnModel::removeColumn: invalid column implementation!" );
+ pColumnImpl->setIndex( columnIndex );
+ }
+
+ // fire removal notifications
+ ContainerEvent aEvent;
+ aEvent.Source = *this;
+ aEvent.Accessor <<= i_columnIndex;
+ aEvent.Element <<= xColumn;
+
+ aGuard.clear();
+ m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvent );
+
+ // dispose the removed column
+ try
+ {
+ Reference< XComponent > const xColComp( xColumn, UNO_QUERY_THROW );
+ xColComp->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
}
- else
- return Reference< XGridColumn >();
-}
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridColumnModel::setColumnHeaderHeight(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException)
-{
- m_nColumnHeaderHeight = _value;
-}
-//---------------------------------------------------------------------
-sal_Int32 SAL_CALL DefaultGridColumnModel::getColumnHeaderHeight() throw (::com::sun::star::uno::RuntimeException)
-{
- return m_nColumnHeaderHeight;
-}
-
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (::com::sun::star::uno::RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- for(sal_Int32 i=0;i<rowElements;i++)
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< Reference< XGridColumn > > SAL_CALL DefaultGridColumnModel::getColumns() throw (RuntimeException)
{
- Reference<XGridColumn> xColumn( m_xFactory->createInstance ( OUString::createFromAscii( "com.sun.star.awt.grid.GridColumn" ) ), UNO_QUERY );
- columns.push_back(xColumn);
- xColumn->setIndex(i);
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return ::comphelper::containerToSequence( m_aColumns );
}
-}
-::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL DefaultGridColumnModel::copyColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException)
-{
- Reference<XGridColumn> xColumn( m_xFactory->createInstance ( OUString::createFromAscii( "com.sun.star.awt.grid.GridColumn" ) ), UNO_QUERY );
- xColumn->setColumnWidth(column->getColumnWidth());
- xColumn->setPreferredWidth(column->getPreferredWidth());
- xColumn->setMaxWidth(column->getMaxWidth());
- xColumn->setMinWidth(column->getMinWidth());
- xColumn->setPreferredWidth(column->getPreferredWidth());
- xColumn->setResizeable(column->getResizeable());
- xColumn->setTitle(column->getTitle());
- xColumn->setHorizontalAlign(column->getHorizontalAlign());
- return xColumn;
-}
-//---------------------------------------------------------------------
-// XComponent
-//---------------------------------------------------------------------
-
-void SAL_CALL DefaultGridColumnModel::dispose() throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- ::com::sun::star::lang::EventObject aEvent;
- aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) );
- BrdcstHelper.aLC.disposeAndClear( aEvent );
-
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XGridColumn > SAL_CALL DefaultGridColumnModel::getColumn(::sal_Int32 index) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-//---------------------------------------------------------------------
+ if ( index >=0 && index < ((sal_Int32)m_aColumns.size()))
+ return m_aColumns[index];
-void SAL_CALL DefaultGridColumnModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.addListener( XEventListener::static_type(), xListener );
-}
+ throw IndexOutOfBoundsException();
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridColumnModel::setDefaultColumns(sal_Int32 rowElements) throw (RuntimeException)
+ {
+ ::std::vector< ContainerEvent > aRemovedColumns;
+ ::std::vector< ContainerEvent > aInsertedColumns;
+
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+
+ // remove existing columns
+ while ( !m_aColumns.empty() )
+ {
+ const size_t lastColIndex = m_aColumns.size() - 1;
+
+ ContainerEvent aEvent;
+ aEvent.Source = *this;
+ aEvent.Accessor <<= sal_Int32( lastColIndex );
+ aEvent.Element <<= m_aColumns[ lastColIndex ];
+ aRemovedColumns.push_back( aEvent );
+
+ m_aColumns.erase( m_aColumns.begin() + lastColIndex );
+ }
+
+ // add new columns
+ for ( sal_Int32 i=0; i<rowElements; ++i )
+ {
+ ::rtl::Reference< GridColumn > const pGridColumn = new GridColumn();
+ Reference< XGridColumn > const xColumn( pGridColumn.get() );
+ ::rtl::OUStringBuffer colTitle;
+ colTitle.appendAscii( "Column " );
+ colTitle.append( i + 1 );
+ pGridColumn->setTitle( colTitle.makeStringAndClear() );
+ pGridColumn->setColumnWidth( 80 /* APPFONT */ );
+ pGridColumn->setFlexibility( 1 );
+ pGridColumn->setResizeable( sal_True );
+ pGridColumn->setDataColumnIndex( i );
+
+ ContainerEvent aEvent;
+ aEvent.Source = *this;
+ aEvent.Accessor <<= i;
+ aEvent.Element <<= xColumn;
+ aInsertedColumns.push_back( aEvent );
+
+ m_aColumns.push_back( xColumn );
+ pGridColumn->setIndex( i );
+ }
+ }
+
+ // fire removal notifications
+ for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
+ event != aRemovedColumns.end();
+ ++event
+ )
+ {
+ m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, *event );
+ }
+
+ // fire insertion notifications
+ for ( ::std::vector< ContainerEvent >::const_iterator event = aInsertedColumns.begin();
+ event != aInsertedColumns.end();
+ ++event
+ )
+ {
+ m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, *event );
+ }
+
+ // dispose removed columns
+ for ( ::std::vector< ContainerEvent >::const_iterator event = aRemovedColumns.begin();
+ event != aRemovedColumns.end();
+ ++event
+ )
+ {
+ try
+ {
+ const Reference< XComponent > xColComp( event->Element, UNO_QUERY_THROW );
+ xColComp->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+ }
-void SAL_CALL DefaultGridColumnModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.removeListener( XEventListener::static_type(), xListener );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL DefaultGridColumnModel::getImplementationName( ) throw (RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.toolkit.DefaultGridColumnModel" ) );
+ }
-//---------------------------------------------------------------------
-// XServiceInfo
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const ::rtl::OUString& i_serviceName ) throw (RuntimeException)
+ {
+ const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
+ for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
+ if ( aServiceNames[i] == i_serviceName )
+ return sal_True;
+ return sal_False;
+ }
-::rtl::OUString SAL_CALL DefaultGridColumnModel::getImplementationName( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.DefaultGridColumnModel" ) );
- return aImplName;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ const ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( szServiceName_DefaultGridColumnModel ) );
+ const Sequence< ::rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridColumnModel::addContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
+ {
+ if ( i_listener.is() )
+ m_aContainerListeners.addInterface( i_listener );
+ }
-sal_Bool SAL_CALL DefaultGridColumnModel::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- return ServiceName.equalsAscii( szServiceName_DefaultGridColumnModel );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridColumnModel::removeContainerListener( const Reference< XContainerListener >& i_listener ) throw (RuntimeException)
+ {
+ if ( i_listener.is() )
+ m_aContainerListeners.removeInterface( i_listener );
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridColumnModel::disposing()
+ {
+ DefaultGridColumnModel_Base::disposing();
+
+ EventObject aEvent( *this );
+ m_aContainerListeners.disposeAndClear( aEvent );
+
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // remove, dispose and clear columns
+ while ( !m_aColumns.empty() )
+ {
+ try
+ {
+ const Reference< XComponent > xColComponent( m_aColumns[ 0 ], UNO_QUERY_THROW );
+ xColComponent->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+
+ m_aColumns.erase( m_aColumns.begin() );
+ }
+
+ Columns aEmpty;
+ m_aColumns.swap( aEmpty );
+ }
-::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridColumnModel::getSupportedServiceNames( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aServiceName( OUString::createFromAscii( szServiceName_DefaultGridColumnModel ) );
- static const Sequence< OUString > aSeq( &aServiceName, 1 );
- return aSeq;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XCloneable > SAL_CALL DefaultGridColumnModel::createClone( ) throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return new DefaultGridColumnModel( *this );
+ }
-}
+//......................................................................................................................
+} // namespace toolkit
+//......................................................................................................................
-Reference< XInterface > SAL_CALL DefaultGridColumnModel_CreateInstance( const Reference< XMultiServiceFactory >& _rFactory)
+//----------------------------------------------------------------------------------------------------------------------
+::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 >& _rFactory)
{
- return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel( _rFactory ) );
+ return ::com::sun::star::uno::Reference < ::com::sun::star::uno::XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::DefaultGridColumnModel( _rFactory ) );
}
-
diff --git a/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx
index 8b8c8bfc795c..da0ef20e3287 100644
--- a/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx
+++ b/toolkit/source/controls/grid/defaultgridcolumnmodel.hxx
@@ -25,76 +25,73 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_toolkit.hxx"
+/** === begin UNO includes === **/
#include <com/sun/star/awt/grid/XGridColumnModel.hpp>
#include <com/sun/star/awt/grid/XGridColumn.hpp>
-//#include <com/sun/star/awt/grid/GridColumnEvent.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
-#include <cppuhelper/implbase2.hxx>
-#include <cppuhelper/implbase3.hxx>
-#include <rtl/ref.hxx>
-#include <vector>
-#include <toolkit/helper/mutexandbroadcasthelper.hxx>
-#include <com/sun/star/util/Color.hpp>
#include <com/sun/star/style/VerticalAlignment.hpp>
-#include <com/sun/star/awt/grid/XGridColumnListener.hpp>
+#include <com/sun/star/util/Color.hpp>
+/** === end UNO includes === **/
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::lang;
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <comphelper/componentcontext.hxx>
+#include <vector>
+
+namespace comphelper
+{
+ class ComponentGuard;
+}
namespace toolkit
{
//enum broadcast_type { column_added, column_removed, column_changed};
-class DefaultGridColumnModel : public ::cppu::WeakImplHelper2< XGridColumnModel, XServiceInfo >,
- public MutexAndBroadcastHelper
+typedef ::cppu::WeakComponentImplHelper2 < ::com::sun::star::awt::grid::XGridColumnModel
+ , ::com::sun::star::lang::XServiceInfo
+ > DefaultGridColumnModel_Base;
+
+class DefaultGridColumnModel :public ::cppu::BaseMutex
+ ,public DefaultGridColumnModel_Base
{
public:
- DefaultGridColumnModel(const Reference< XMultiServiceFactory >& xFactory);
+ DefaultGridColumnModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory );
+ DefaultGridColumnModel( DefaultGridColumnModel const & i_copySource );
virtual ~DefaultGridColumnModel();
// XGridColumnModel
-
- //virtual ::sal_Bool SAL_CALL getColumnSelectionAllowed() throw (::com::sun::star::uno::RuntimeException);
- //virtual void SAL_CALL setColumnSelectionAllowed(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getColumnCount() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Int32 SAL_CALL addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL createColumn( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL addColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException);
+ virtual void SAL_CALL removeColumn( ::sal_Int32 i_columnIndex ) throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > SAL_CALL getColumns() throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
- //virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException);
- //virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL setColumnHeaderHeight( sal_Int32 _value) throw (com::sun::star::uno::RuntimeException);
- virtual sal_Int32 SAL_CALL getColumnHeaderHeight() throw (com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL getColumn(::sal_Int32 index) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setDefaultColumns(sal_Int32 rowElements) throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > SAL_CALL copyColumn(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & column) throw (::com::sun::star::uno::RuntimeException);
- // XComponent
- virtual void SAL_CALL dispose( ) throw (RuntimeException);
- virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (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);
-private:
- /*void broadcast( broadcast_type eType, const GridColumnEvent& aEvent );
- void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue, sal_Int32 index,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn );
- void broadcast_add( sal_Int32 index,const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn );
- void broadcast_remove( sal_Int32 index, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > & rColumn );*/
+ // XContainer
+ virtual void SAL_CALL addContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeContainerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XCloneable
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::util::XCloneable > SAL_CALL createClone( ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+private:
+ typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > Columns;
- std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumn > > columns;
- sal_Bool selectionAllowed;
- sal_Int32 m_nColumnHeaderHeight;
- Reference< XMultiServiceFactory > m_xFactory;
+ ::comphelper::ComponentContext m_aContext;
+ ::cppu::OInterfaceContainerHelper m_aContainerListeners;
+ Columns m_aColumns;
};
}
diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.cxx b/toolkit/source/controls/grid/defaultgriddatamodel.cxx
index adc40b0426d7..4ef99d749ba1 100644
--- a/toolkit/source/controls/grid/defaultgriddatamodel.cxx
+++ b/toolkit/source/controls/grid/defaultgriddatamodel.cxx
@@ -27,318 +27,411 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
+
#include "defaultgriddatamodel.hxx"
-#include <comphelper/sequence.hxx>
+
+#include <comphelper/stlunosequence.hxx>
+#include <comphelper/componentguard.hxx>
#include <toolkit/helper/servicenames.hxx>
+#include <tools/diagnose_ex.h>
#include <rtl/ref.hxx>
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::lang;
-
-#define ROWHEIGHT ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeight" ))
-#define ROWHEADERS ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeaders" ))
-#define CELLUPDATED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "CellUpdated" ))
-#define ROWUPDATED ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowUpdated" ))
-#define ROWHEADERWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "RowHeaderWidth" ))
+#include <algorithm>
+//......................................................................................................................
namespace toolkit
+//......................................................................................................................
{
+ /** === begin UNO using === **/
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::RuntimeException;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::UNO_QUERY_THROW;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::uno::XInterface;
+ using ::com::sun::star::lang::XComponent;
+ using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::util::XCloneable;
+ /** === end UNO using === **/
+
+ using ::comphelper::stl_begin;
+ using ::comphelper::stl_end;
+
+ //==================================================================================================================
+ //= DefaultGridDataModel
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::DefaultGridDataModel()
+ :DefaultGridDataModel_Base( m_aMutex )
+ ,m_aRowHeaders()
+ ,m_nColumnCount(0)
+ {
+ }
-///////////////////////////////////////////////////////////////////////
-// class DefaultGridDataModel
-///////////////////////////////////////////////////////////////////////
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::DefaultGridDataModel( DefaultGridDataModel const & i_copySource )
+ :cppu::BaseMutex()
+ ,DefaultGridDataModel_Base( m_aMutex )
+ ,m_aData( i_copySource.m_aData )
+ ,m_aRowHeaders( i_copySource.m_aRowHeaders )
+ ,m_nColumnCount( i_copySource.m_nColumnCount )
+ {
+ }
-DefaultGridDataModel::DefaultGridDataModel()
-: rowHeight(0),
- rowHeaders(std::vector< ::rtl::OUString >()),
- m_nRowHeaderWidth(10)
-{
-}
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::~DefaultGridDataModel()
+ {
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void DefaultGridDataModel::broadcast( GridDataEvent const & i_event,
+ void ( SAL_CALL XGridDataListener::*i_listenerMethod )( GridDataEvent const & ), ::comphelper::ComponentGuard & i_instanceLock )
+ {
+ ::cppu::OInterfaceContainerHelper* pListeners = rBHelper.getContainer( XGridDataListener::static_type() );
+ if ( !pListeners )
+ return;
-DefaultGridDataModel::~DefaultGridDataModel()
-{
-}
+ i_instanceLock.clear();
+ pListeners->notifyEach( i_listenerMethod, i_event );
+ }
-void DefaultGridDataModel::broadcast( broadcast_type eType, const GridDataEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException)
-{
- ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridDataListener::static_type() );
- if( pIter )
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL DefaultGridDataModel::getRowCount() throw (::com::sun::star::uno::RuntimeException)
{
- ::cppu::OInterfaceIteratorHelper aListIter(*pIter);
- while(aListIter.hasMoreElements())
- {
- XGridDataListener* pListener = static_cast<XGridDataListener*>(aListIter.next());
- switch( eType )
- {
- case row_added: pListener->rowAdded(aEvent); break;
- case row_removed: pListener->rowRemoved(aEvent); break;
- case data_changed: pListener->dataChanged(aEvent); break;
- }
- }
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_aData.size();
}
-}
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL DefaultGridDataModel::getColumnCount() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nColumnCount;
+ }
-void DefaultGridDataModel::broadcast_changed( ::rtl::OUString name, sal_Int32 index, Any oldValue, Any newValue) throw (::com::sun::star::uno::RuntimeException)
-{
- Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
- GridDataEvent aEvent( xSource, name, oldValue, newValue, index, ::rtl::OUString(), Sequence< Any >());
- broadcast( data_changed, aEvent);
-}
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::CellData const & DefaultGridDataModel::impl_getCellData_throw( sal_Int32 const i_column, sal_Int32 const i_row ) const
+ {
+ if ( ( i_row < 0 ) || ( size_t( i_row ) > m_aData.size() )
+ || ( i_column < 0 ) || ( i_column > m_nColumnCount )
+ )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< DefaultGridDataModel* >( this ) );
-//---------------------------------------------------------------------
+ RowData const & rRow( m_aData[ i_row ] );
+ if ( size_t( i_column ) < rRow.size() )
+ return rRow[ i_column ];
-void DefaultGridDataModel::broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName,
- ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException)
-{
- Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
- GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, (const ::com::sun::star::uno::Sequence< Any >&)rowData );
- broadcast( row_added, aEvent);
-}
+ static CellData s_aEmpty;
+ return s_aEmpty;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::RowData& DefaultGridDataModel::impl_getRowDataAccess_throw( sal_Int32 const i_rowIndex, size_t const i_requiredColumnCount )
+ {
+ OSL_ENSURE( i_requiredColumnCount <= size_t( m_nColumnCount ), "DefaultGridDataModel::impl_getRowDataAccess_throw: invalid column count!" );
+ if ( ( i_rowIndex < 0 ) || ( size_t( i_rowIndex ) >= m_aData.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
+
+ RowData& rRowData( m_aData[ i_rowIndex ] );
+ if ( rRowData.size() < i_requiredColumnCount )
+ rRowData.resize( i_requiredColumnCount );
+ return rRowData;
+ }
-void DefaultGridDataModel::broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName,
- ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException)
-{
- Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
- GridDataEvent aEvent( xSource, ::rtl::OUString(), Any(), Any(), index, headerName, rowData );
- broadcast( row_removed, aEvent);
-}
+ //------------------------------------------------------------------------------------------------------------------
+ DefaultGridDataModel::CellData& DefaultGridDataModel::impl_getCellDataAccess_throw( sal_Int32 const i_columnIndex, sal_Int32 const i_rowIndex )
+ {
+ if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= m_nColumnCount ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
-//---------------------------------------------------------------------
+ RowData& rRowData( impl_getRowDataAccess_throw( i_rowIndex, size_t( i_columnIndex + 1 ) ) );
+ return rRowData[ i_columnIndex ];
+ }
-//---------------------------------------------------------------------
-// XDefaultGridDataModel
-//---------------------------------------------------------------------
-::sal_Int32 SAL_CALL DefaultGridDataModel::getRowHeight() throw (::com::sun::star::uno::RuntimeException)
-{
- return rowHeight;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL DefaultGridDataModel::getCellData( ::sal_Int32 i_column, ::sal_Int32 i_row ) throw (RuntimeException, IndexOutOfBoundsException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return impl_getCellData_throw( i_column, i_row ).first;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL DefaultGridDataModel::getCellToolTip( ::sal_Int32 i_column, ::sal_Int32 i_row ) throw (RuntimeException, IndexOutOfBoundsException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return impl_getCellData_throw( i_column, i_row ).second;
+ }
-void SAL_CALL DefaultGridDataModel::setRowHeight(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
-{
- sal_Int32 oldValue = rowHeight;
- rowHeight = value;
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL DefaultGridDataModel::getRowHeading( ::sal_Int32 i_row ) throw (RuntimeException, IndexOutOfBoundsException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
- broadcast_changed( ROWHEIGHT, 0, Any(oldValue), Any(value));
-}
+ if ( ( i_row < 0 ) || ( size_t( i_row ) >= m_aRowHeaders.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
-//---------------------------------------------------------------------
+ return m_aRowHeaders[ i_row ];
+ }
-::sal_Int32 SAL_CALL DefaultGridDataModel::getRowCount() throw (::com::sun::star::uno::RuntimeException)
-{
- return data.size();
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::addRow( const Any& i_heading, const Sequence< Any >& i_data ) throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-//---------------------------------------------------------------------
+ sal_Int32 const columnCount = i_data.getLength();
-::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridDataModel::getRowHeaders() throw (::com::sun::star::uno::RuntimeException)
-{
- return comphelper::containerToSequence(rowHeaders);
-}
+ // store header name
+ m_aRowHeaders.push_back( i_heading );
-//---------------------------------------------------------------------
+ // store row m_aData
+ impl_addRow( i_data );
-void SAL_CALL DefaultGridDataModel::setRowHeaders(const ::com::sun::star::uno::Sequence< ::rtl::OUString > & value) throw (::com::sun::star::uno::RuntimeException)
-{
- ::com::sun::star::uno::Sequence< ::rtl::OUString > oldValue( comphelper::containerToSequence(rowHeaders) );
+ // update column count
+ if ( columnCount > m_nColumnCount )
+ m_nColumnCount = columnCount;
- std::vector< rtl::OUString>::iterator iterator;
- int i = 0;
- int sequenceSize = value.getLength();
+ sal_Int32 const rowIndex = sal_Int32( m_aData.size() - 1 );
+ broadcast(
+ GridDataEvent( *this, -1, -1, rowIndex, rowIndex ),
+ &XGridDataListener::rowsInserted,
+ aGuard
+ );
+ }
- for(iterator = rowHeaders.begin(); iterator != rowHeaders.end(); iterator++)
+ //------------------------------------------------------------------------------------------------------------------
+ void DefaultGridDataModel::impl_addRow( Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount )
{
- if ( sequenceSize > i )
- *iterator = value[i];
- else
- *iterator = ::rtl::OUString();
- i++;
+ OSL_PRECOND( ( i_assumedColCount <= 0 ) || ( i_assumedColCount >= i_rowData.getLength() ),
+ "DefaultGridDataModel::impl_addRow: invalid column count!" );
+
+ RowData newRow( i_assumedColCount > 0 ? i_assumedColCount : i_rowData.getLength() );
+ RowData::iterator cellData = newRow.begin();
+ for ( const Any* pData = stl_begin( i_rowData ); pData != stl_end( i_rowData ); ++pData, ++cellData )
+ cellData->first = *pData;
+
+ m_aData.push_back( newRow );
}
- broadcast_changed( ROWHEADERS, 0, Any(oldValue), Any(comphelper::containerToSequence(rowHeaders)) );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::addRows( const Sequence< Any >& i_headings, const Sequence< Sequence< Any > >& i_data ) throw (IllegalArgumentException, RuntimeException)
+ {
+ if ( i_headings.getLength() != i_data.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, -1 );
-//---------------------------------------------------------------------
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-void SAL_CALL DefaultGridDataModel::addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< Any > & rRowdata) throw (::com::sun::star::uno::RuntimeException)
-{
- // store header name
- rowHeaders.push_back(headername);
+ sal_Int32 const rowCount = i_headings.getLength();
+ if ( rowCount == 0 )
+ return;
- // store row data
- std::vector< Any > newRow;
- for ( int i = 0; i < rRowdata.getLength();i++)
- {
- newRow.push_back(rRowdata[i]);
- }
+ // determine max col count in the new data
+ sal_Int32 maxColCount = 0;
+ for ( sal_Int32 row=0; row<rowCount; ++row )
+ if ( i_data[row].getLength() > maxColCount )
+ maxColCount = i_data[row].getLength();
- data.push_back( newRow );
+ if ( maxColCount < m_nColumnCount )
+ maxColCount = m_nColumnCount;
- broadcast_add( data.size()-1, headername, comphelper::containerToSequence(newRow));
+ for ( sal_Int32 row=0; row<rowCount; ++row )
+ {
+ m_aRowHeaders.push_back( i_headings[row] );
+ impl_addRow( i_data[row], maxColCount );
+ }
-}
+ if ( maxColCount > m_nColumnCount )
+ m_nColumnCount = maxColCount;
-//---------------------------------------------------------------------
+ sal_Int32 const firstRow = sal_Int32( m_aData.size() - rowCount );
+ sal_Int32 const lastRow = sal_Int32( m_aData.size() - 1 );
+ broadcast(
+ GridDataEvent( *this, -1, -1, firstRow, lastRow ),
+ &XGridDataListener::rowsInserted,
+ aGuard
+ );
+ }
-void SAL_CALL DefaultGridDataModel::removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
-{
- if ( index >= 0 && index <= getRowCount()-1)
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::removeRow( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
{
- ::rtl::OUString headerName( (::rtl::OUString) rowHeaders[index] );
- rowHeaders.erase(rowHeaders.begin() + index);
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
- Sequence< Any > rowData ( (Sequence< Any >&)data[index] );
- data.erase(data.begin() + index);
- broadcast_remove( index, headerName, rowData);
+ if ( ( i_rowIndex < 0 ) || ( size_t( i_rowIndex ) >= m_aData.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
+
+ m_aRowHeaders.erase( m_aRowHeaders.begin() + i_rowIndex );
+ m_aData.erase( m_aData.begin() + i_rowIndex );
+
+ broadcast(
+ GridDataEvent( *this, -1, -1, i_rowIndex, i_rowIndex ),
+ &XGridDataListener::rowsRemoved,
+ aGuard
+ );
}
- else
- return;
-}
-//---------------------------------------------------------------------
-::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Any > > SAL_CALL DefaultGridDataModel::getData() throw (::com::sun::star::uno::RuntimeException)
-{
- std::vector< std::vector< Any > >::iterator iterator;
- std::vector< Sequence< Any > > dummyContainer(0);
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::removeAllRows( ) throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+
+ m_aRowHeaders.clear();
+ m_aData.clear();
+ broadcast(
+ GridDataEvent( *this, -1, -1, -1, -1 ),
+ &XGridDataListener::rowsRemoved,
+ aGuard
+ );
+ }
- for(iterator = data.begin(); iterator != data.end(); iterator++)
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::updateCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
{
- Sequence< Any > cols(comphelper::containerToSequence(*iterator));
- dummyContainer.push_back( cols );
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+
+ impl_getCellDataAccess_throw( i_columnIndex, i_rowIndex ).first = i_value;
+
+ broadcast(
+ GridDataEvent( *this, i_columnIndex, i_columnIndex, i_rowIndex, i_rowIndex ),
+ &XGridDataListener::dataChanged,
+ aGuard
+ );
}
- Sequence< Sequence< Any > > dataSequence(comphelper::containerToSequence(dummyContainer));
- return dataSequence;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::updateRowData( const Sequence< ::sal_Int32 >& i_columnIndexes, ::sal_Int32 i_rowIndex, const Sequence< Any >& i_values ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-//---------------------------------------------------------------------
+ if ( ( i_rowIndex < 0 ) || ( size_t( i_rowIndex ) >= m_aData.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
-void SAL_CALL DefaultGridDataModel::addDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.addListener( XGridDataListener::static_type(), xListener );
-}
+ if ( i_columnIndexes.getLength() != i_values.getLength() )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
-//---------------------------------------------------------------------
+ sal_Int32 const columnCount = i_columnIndexes.getLength();
+ if ( columnCount == 0 )
+ return;
-void SAL_CALL DefaultGridDataModel::removeDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.removeListener( XGridDataListener::static_type(), xListener );
-}
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridDataModel::removeAll() throw (RuntimeException)
-{
- rowHeaders.clear();
- data.clear();
- broadcast_remove( -1, ::rtl::OUString(), Sequence< Any >());
-}
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridDataModel::setRowHeaderWidth(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException)
-{
- sal_Int32 oldValue = m_nRowHeaderWidth;
- m_nRowHeaderWidth = _value;
- broadcast_changed( ROWHEADERWIDTH, 0, Any(oldValue), Any(_value) );
-}
-//---------------------------------------------------------------------
-sal_Int32 SAL_CALL DefaultGridDataModel::getRowHeaderWidth() throw (::com::sun::star::uno::RuntimeException)
-{
- return m_nRowHeaderWidth;
-}
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridDataModel::updateCell(::sal_Int32 row, ::sal_Int32 column, const Any& value) throw (::com::sun::star::uno::RuntimeException)
-{
- if(row >= 0 && row < (signed)data.size())
- {
- if(column >= 0 && column < (signed)data[0].size())
+ for ( sal_Int32 col = 0; col < columnCount; ++col )
{
- data[row][column] = value;
- Sequence< Any >dataSeq(comphelper::containerToSequence(data[row]));
- broadcast_changed( CELLUPDATED, row, Any(column), value );
+ if ( ( i_columnIndexes[col] < 0 ) || ( i_columnIndexes[col] > m_nColumnCount ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
}
- }
-}
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridDataModel::updateRow(::sal_Int32 row, const ::com::sun::star::uno::Sequence< ::sal_Int32 > & columns, const ::com::sun::star::uno::Sequence< Any > & values) throw (::com::sun::star::uno::RuntimeException)
-{
- if(row >= 0 && row < (signed)data.size())
- {
- if(columns.getLength() == values.getLength())
+
+ RowData& rDataRow = m_aData[ i_rowIndex ];
+ for ( sal_Int32 col = 0; col < columnCount; ++col )
{
- for(int i = 0; i < columns.getLength(); i++)
- data[row][i] = values[i];
- Sequence< Any >dataSeq(comphelper::containerToSequence(data[row]));
- broadcast_changed( ROWUPDATED, row, Any(columns), Any(values) );
+ sal_Int32 const columnIndex = i_columnIndexes[ col ];
+ if ( size_t( columnIndex ) >= rDataRow.size() )
+ rDataRow.resize( columnIndex + 1 );
+
+ rDataRow[ columnIndex ].first = i_values[ col ];
}
+
+ sal_Int32 const firstAffectedColumn = *::std::min_element( stl_begin( i_columnIndexes ), stl_end( i_columnIndexes ) );
+ sal_Int32 const lastAffectedColumn = *::std::max_element( stl_begin( i_columnIndexes ), stl_end( i_columnIndexes ) );
+ broadcast(
+ GridDataEvent( *this, firstAffectedColumn, lastAffectedColumn, i_rowIndex, i_rowIndex ),
+ &XGridDataListener::dataChanged,
+ aGuard
+ );
}
-}
-//---------------------------------------------------------------------
-// XComponent
-//---------------------------------------------------------------------
-void SAL_CALL DefaultGridDataModel::dispose() throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::updateRowHeading( ::sal_Int32 i_rowIndex, const Any& i_heading ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
- ::com::sun::star::lang::EventObject aEvent;
- aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) );
- BrdcstHelper.aLC.disposeAndClear( aEvent );
+ if ( ( i_rowIndex < 0 ) || ( size_t( i_rowIndex ) >= m_aRowHeaders.size() ) )
+ throw IndexOutOfBoundsException( ::rtl::OUString(), *this );
-}
+ m_aRowHeaders[ i_rowIndex ] = i_heading;
-//---------------------------------------------------------------------
+ broadcast(
+ GridDataEvent( *this, -1, -1, i_rowIndex, i_rowIndex ),
+ &XGridDataListener::rowHeadingChanged,
+ aGuard
+ );
+ }
-void SAL_CALL DefaultGridDataModel::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.addListener( XEventListener::static_type(), xListener );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::updateCellToolTip( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ impl_getCellDataAccess_throw( i_columnIndex, i_rowIndex ).second = i_value;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::updateRowToolTip( ::sal_Int32 i_rowIndex, const Any& i_value ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
-void SAL_CALL DefaultGridDataModel::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.removeListener( XEventListener::static_type(), xListener );
-}
-//---------------------------------------------------------------------
-// XServiceInfo
-//---------------------------------------------------------------------
+ RowData& rRowData = impl_getRowDataAccess_throw( i_rowIndex, m_nColumnCount );
+ for ( RowData::iterator cell = rRowData.begin(); cell != rRowData.end(); ++cell )
+ cell->second = i_value;
+ }
-::rtl::OUString SAL_CALL DefaultGridDataModel::getImplementationName( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.DefaultGridDataModel" ) );
- return aImplName;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::addGridDataListener( const Reference< grid::XGridDataListener >& i_listener ) throw (RuntimeException)
+ {
+ rBHelper.addListener( XGridDataListener::static_type(), i_listener );
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::removeGridDataListener( const Reference< grid::XGridDataListener >& i_listener ) throw (RuntimeException)
+ {
+ rBHelper.removeListener( XGridDataListener::static_type(), i_listener );
+ }
-sal_Bool SAL_CALL DefaultGridDataModel::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- return ServiceName.equalsAscii( szServiceName_DefaultGridDataModel );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL DefaultGridDataModel::disposing()
+ {
+ ::com::sun::star::lang::EventObject aEvent;
+ aEvent.Source.set( *this );
+ rBHelper.aLC.disposeAndClear( aEvent );
-//---------------------------------------------------------------------
+ ::osl::MutexGuard aGuard( m_aMutex );
+ GridData aEmptyData;
+ m_aData.swap( aEmptyData );
-::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL DefaultGridDataModel::getSupportedServiceNames( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aServiceName( OUString::createFromAscii( szServiceName_DefaultGridDataModel ) );
- static const Sequence< OUString > aSeq( &aServiceName, 1 );
- return aSeq;
-}
+ ::std::vector< Any > aEmptyRowHeaders;
+ m_aRowHeaders.swap( aEmptyRowHeaders );
-}
+ m_nColumnCount = 0;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL DefaultGridDataModel::getImplementationName( ) throw (RuntimeException)
+ {
+ static const ::rtl::OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.DefaultGridDataModel" ) );
+ return aImplName;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL DefaultGridDataModel::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
+ {
+ return ServiceName.equalsAscii( szServiceName_DefaultGridDataModel );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::rtl::OUString > SAL_CALL DefaultGridDataModel::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ static const ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( szServiceName_DefaultGridDataModel ) );
+ static const Sequence< ::rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XCloneable > SAL_CALL DefaultGridDataModel::createClone( ) throw (RuntimeException)
+ {
+ return new DefaultGridDataModel( *this );
+ }
+
+//......................................................................................................................
+} // namespace toolkit
+//......................................................................................................................
Reference< XInterface > SAL_CALL DefaultGridDataModel_CreateInstance( const Reference< XMultiServiceFactory >& )
{
diff --git a/toolkit/source/controls/grid/defaultgriddatamodel.hxx b/toolkit/source/controls/grid/defaultgriddatamodel.hxx
index ea11a8a9a00a..bf4b6cc3355e 100644
--- a/toolkit/source/controls/grid/defaultgriddatamodel.hxx
+++ b/toolkit/source/controls/grid/defaultgriddatamodel.hxx
@@ -25,60 +25,68 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_toolkit.hxx"
-#include <com/sun/star/awt/grid/XGridDataModel.hpp>
-#include <com/sun/star/awt/grid/GridDataEvent.hpp>
-#include <com/sun/star/awt/grid/XGridDataListener.hpp>
-#include <com/sun/star/awt/XControl.hpp>
-#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/awt/grid/XMutableGridDataModel.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/lang/XUnoTunnel.hpp>
-#include <cppuhelper/implbase2.hxx>
-#include <cppuhelper/implbase3.hxx>
-#include <rtl/ref.hxx>
-#include <vector>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase2.hxx>
#include <toolkit/helper/mutexandbroadcasthelper.hxx>
-using ::rtl::OUString;
+#include <vector>
+
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::awt::grid;
using namespace ::com::sun::star::lang;
+namespace comphelper
+{
+ class ComponentGuard;
+}
+
namespace toolkit
{
enum broadcast_type { row_added, row_removed, data_changed};
-class DefaultGridDataModel : public ::cppu::WeakImplHelper2< XGridDataModel, XServiceInfo >,
- public MutexAndBroadcastHelper
+typedef ::cppu::WeakComponentImplHelper2 < XMutableGridDataModel
+ , XServiceInfo
+ > DefaultGridDataModel_Base;
+
+class DefaultGridDataModel :public ::cppu::BaseMutex
+ ,public DefaultGridDataModel_Base
{
public:
DefaultGridDataModel();
+ DefaultGridDataModel( DefaultGridDataModel const & i_copySource );
virtual ~DefaultGridDataModel();
+ // XMutableGridDataModel
+ virtual void SAL_CALL addRow( const Any& i_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 updateRowHeading( ::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 getRowHeight() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setRowHeight(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getRowCount() throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getRowHeaders() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setRowHeaders(const ::com::sun::star::uno::Sequence< ::rtl::OUString > & value) throw (::com::sun::star::uno::RuntimeException);
- virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< Any > > SAL_CALL getData() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addRow(const ::rtl::OUString & headername, const ::com::sun::star::uno::Sequence< Any > & data) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL removeRow(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL removeDataListener( const Reference< XGridDataListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL removeAll() throw (RuntimeException);
- virtual void SAL_CALL setRowHeaderWidth(sal_Int32 _value) throw (::com::sun::star::uno::RuntimeException);
- virtual sal_Int32 SAL_CALL getRowHeaderWidth() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL updateCell( ::sal_Int32 row, ::sal_Int32 column, const ::com::sun::star::uno::Any& value ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL updateRow( ::sal_Int32 row, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& values ) throw (::com::sun::star::uno::RuntimeException);
- // XComponent
- virtual void SAL_CALL dispose( ) throw (RuntimeException);
- virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (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 (RuntimeException);
@@ -86,16 +94,25 @@ public:
virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
private:
+ typedef ::std::pair< Any, Any > CellData;
+ typedef ::std::vector< CellData > RowData;
+ typedef ::std::vector< RowData > GridData;
+
+ void broadcast(
+ GridDataEvent const & i_event,
+ void ( SAL_CALL ::com::sun::star::awt::grid::XGridDataListener::*i_listenerMethod )( ::com::sun::star::awt::grid::GridDataEvent const & ),
+ ::comphelper::ComponentGuard & i_instanceLock
+ );
+
+ void impl_addRow( Sequence< Any > const & i_rowData, sal_Int32 const i_assumedColCount = -1 );
- void broadcast( broadcast_type eType, const GridDataEvent& aEvent ) throw (::com::sun::star::uno::RuntimeException);
- void broadcast_changed( ::rtl::OUString name, sal_Int32 index, Any oldValue, Any newValue ) throw (::com::sun::star::uno::RuntimeException);
- void broadcast_add( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException);
- void broadcast_remove( sal_Int32 index, const ::rtl::OUString & headerName, const ::com::sun::star::uno::Sequence< Any > rowData ) throw (::com::sun::star::uno::RuntimeException);
+ CellData const & impl_getCellData_throw( sal_Int32 const i_columnIndex, sal_Int32 const i_rowIndex ) const;
+ CellData& impl_getCellDataAccess_throw( sal_Int32 const i_columnIndex, sal_Int32 const i_rowIndex );
+ RowData& impl_getRowDataAccess_throw( sal_Int32 const i_rowIndex, size_t const i_requiredColumnCount );
- sal_Int32 rowHeight;
- std::vector< std::vector < Any > > data;
- std::vector< ::rtl::OUString > rowHeaders;
- sal_Int32 m_nRowHeaderWidth;
+ GridData m_aData;
+ ::std::vector< ::com::sun::star::uno::Any > m_aRowHeaders;
+ sal_Int32 m_nColumnCount;
};
}
diff --git a/toolkit/source/controls/grid/gridcolumn.cxx b/toolkit/source/controls/grid/gridcolumn.cxx
index 6720d639f5c1..c1216d53f328 100644
--- a/toolkit/source/controls/grid/gridcolumn.cxx
+++ b/toolkit/source/controls/grid/gridcolumn.cxx
@@ -25,281 +25,305 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
#include "gridcolumn.hxx"
+
#include <comphelper/sequence.hxx>
+#include <cppuhelper/typeprovider.hxx>
#include <toolkit/helper/servicenames.hxx>
-#include <rtl/ref.hxx>
-
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::style;
-
-#define COLWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColWidth" ))
-#define MAXWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MaxWidth" ))
-#define MINWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "MinWidth" ))
-#define PREFWIDTH ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "PrefWidth" ))
-#define HALIGN ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "HAlign" ))
-#define TITLE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Title" ))
-#define COLRESIZE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ColumnResize" ))
-#define UPDATE ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "UpdateWidth" ))
namespace toolkit
{
-
-///////////////////////////////////////////////////////////////////////
-// class GridColumn
-///////////////////////////////////////////////////////////////////////
-
-GridColumn::GridColumn()
-: identifier(Any())
-,index(0)
-,columnWidth(4)
-,preferredWidth(0)
-,maxWidth(0)
-,minWidth(0)
-,bResizeable(true)
-,horizontalAlign(HorizontalAlignment(0))
-{
-}
-
-//---------------------------------------------------------------------
-
-GridColumn::~GridColumn()
-{
-}
-
-//---------------------------------------------------------------------
-
-void GridColumn::broadcast( broadcast_column_type eType, const GridColumnEvent& aEvent )
-{
- ::cppu::OInterfaceContainerHelper* pIter = BrdcstHelper.getContainer( XGridColumnListener::static_type() );
- if( pIter )
- {
- ::cppu::OInterfaceIteratorHelper aListIter(*pIter);
- while(aListIter.hasMoreElements())
- {
- XGridColumnListener* pListener = static_cast<XGridColumnListener*>(aListIter.next());
- switch( eType )
- {
- case column_attribute_changed: pListener->columnChanged(aEvent); break;
- }
- }
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::awt;
+ using namespace ::com::sun::star::awt::grid;
+ using namespace ::com::sun::star::lang;
+ using namespace ::com::sun::star::util;
+ using namespace ::com::sun::star::style;
+
+ //==================================================================================================================
+ //= DefaultGridColumnModel
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ GridColumn::GridColumn()
+ :GridColumn_Base( m_aMutex )
+ ,m_aIdentifier()
+ ,m_nIndex(-1)
+ ,m_nDataColumnIndex(-1)
+ ,m_nColumnWidth(4)
+ ,m_nMaxWidth(0)
+ ,m_nMinWidth(0)
+ ,m_nFlexibility(1)
+ ,m_bResizeable(true)
+ ,m_eHorizontalAlign( HorizontalAlignment_LEFT )
+ {
}
-}
-
-//---------------------------------------------------------------------
-
-void GridColumn::broadcast_changed(::rtl::OUString name, Any oldValue, Any newValue)
-{
- Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) );
- GridColumnEvent aEvent( xSource, name, oldValue, newValue, index);
- broadcast( column_attribute_changed, aEvent);
-}
-
-void SAL_CALL GridColumn::updateColumn(const ::rtl::OUString& name, sal_Int32 width) throw (::com::sun::star::uno::RuntimeException)
-{
- if(PREFWIDTH == name)
- preferredWidth = width;
- else if (COLWIDTH == name)
- columnWidth = width;
-}
-//---------------------------------------------------------------------
-// XGridColumn
-//---------------------------------------------------------------------
-
-::com::sun::star::uno::Any SAL_CALL GridColumn::getIdentifier() throw (::com::sun::star::uno::RuntimeException)
-{
- return identifier;
-}
-//---------------------------------------------------------------------
-
-void SAL_CALL GridColumn::setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException)
-{
- value >>= identifier;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ GridColumn::GridColumn( GridColumn const & i_copySource )
+ :cppu::BaseMutex()
+ ,GridColumn_Base( m_aMutex )
+ ,m_aIdentifier( i_copySource.m_aIdentifier )
+ ,m_nIndex( -1 )
+ ,m_nDataColumnIndex( i_copySource.m_nDataColumnIndex )
+ ,m_nColumnWidth( i_copySource.m_nColumnWidth )
+ ,m_nMaxWidth( i_copySource.m_nMaxWidth )
+ ,m_nMinWidth( i_copySource.m_nMinWidth )
+ ,m_nFlexibility( i_copySource.m_nFlexibility )
+ ,m_bResizeable( i_copySource.m_bResizeable )
+ ,m_sTitle( i_copySource.m_sTitle )
+ ,m_sHelpText( i_copySource.m_sHelpText )
+ ,m_eHorizontalAlign( i_copySource.m_eHorizontalAlign )
+ {
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ GridColumn::~GridColumn()
+ {
+ }
-::sal_Int32 SAL_CALL GridColumn::getColumnWidth() throw (::com::sun::star::uno::RuntimeException)
-{
- broadcast_changed(UPDATE, Any(columnWidth), Any());
- return columnWidth;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void GridColumn::broadcast_changed( sal_Char const * const i_asciiAttributeName, Any i_oldValue, Any i_newValue,
+ ::comphelper::ComponentGuard& i_Guard )
+ {
+ Reference< XInterface > const xSource( static_cast< ::cppu::OWeakObject* >( this ) );
+ GridColumnEvent const aEvent(
+ xSource, ::rtl::OUString::createFromAscii( i_asciiAttributeName ),
+ i_oldValue, i_newValue, m_nIndex
+ );
-//--------------------------------------------------------------------
+ ::cppu::OInterfaceContainerHelper* pIter = rBHelper.getContainer( XGridColumnListener::static_type() );
-void SAL_CALL GridColumn::setColumnWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
-{
- columnWidth = value;
- broadcast_changed(COLWIDTH, Any(columnWidth),Any(value));
-}
-//--------------------------------------------------------------------
+ i_Guard.clear();
+ if( pIter )
+ pIter->notifyEach( &XGridColumnListener::columnChanged, aEvent );
+ }
-::sal_Int32 SAL_CALL GridColumn::getPreferredWidth() throw (::com::sun::star::uno::RuntimeException)
-{
- broadcast_changed(UPDATE, Any(preferredWidth), Any());
- return preferredWidth;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::com::sun::star::uno::Any SAL_CALL GridColumn::getIdentifier() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_aIdentifier;
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ m_aIdentifier = value;
+ }
-void SAL_CALL GridColumn::setPreferredWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
-{
- preferredWidth = value;
- broadcast_changed(PREFWIDTH, Any(preferredWidth),Any(value));
-}
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getColumnWidth() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nColumnWidth;
+ }
-::sal_Int32 SAL_CALL GridColumn::getMaxWidth() throw (::com::sun::star::uno::RuntimeException)
-{
- return maxWidth;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setColumnWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_nColumnWidth, value, "ColumnWidth" );
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getMaxWidth() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nMaxWidth;
+ }
-void SAL_CALL GridColumn::setMaxWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
-{
- maxWidth = value;
- broadcast_changed(MAXWIDTH, Any(maxWidth),Any(value));
-}
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setMaxWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_nMaxWidth, value, "MaxWidth" );
+ }
-::sal_Int32 SAL_CALL GridColumn::getMinWidth() throw (::com::sun::star::uno::RuntimeException)
-{
- return minWidth;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getMinWidth() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nMinWidth;
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setMinWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_nMinWidth, value, "MinWidth" );
+ }
-void SAL_CALL GridColumn::setMinWidth(::sal_Int32 value) throw (::com::sun::star::uno::RuntimeException)
-{
- minWidth = value;
- broadcast_changed(MINWIDTH, Any(minWidth),Any(value));
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL GridColumn::getTitle() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_sTitle;
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_sTitle, value, "Title" );
+ }
-::rtl::OUString SAL_CALL GridColumn::getTitle() throw (::com::sun::star::uno::RuntimeException)
-{
- return title;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL GridColumn::getHelpText() throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_sHelpText;
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setHelpText( const ::rtl::OUString & value ) throw (RuntimeException)
+ {
+ impl_set( m_sHelpText, value, "HelpText" );
+ }
-void SAL_CALL GridColumn::setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException)
-{
- title = value;
- broadcast_changed(TITLE, Any(title),Any(value));
-}
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL GridColumn::getResizeable() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_bResizeable;
+ }
-sal_Bool SAL_CALL GridColumn::getResizeable() throw (::com::sun::star::uno::RuntimeException)
-{
- return bResizeable;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setResizeable(sal_Bool value) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_bResizeable, value, "Resizeable" );
+ }
-//--------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getFlexibility() throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nFlexibility;
+ }
-void SAL_CALL GridColumn::setResizeable(sal_Bool value) throw (::com::sun::star::uno::RuntimeException)
-{
- bResizeable = value;
- broadcast_changed(COLRESIZE, Any(bResizeable),Any(value));
-}
-//---------------------------------------------------------------------
-HorizontalAlignment SAL_CALL GridColumn::getHorizontalAlign() throw (::com::sun::star::uno::RuntimeException)
-{
- return horizontalAlign;
-}
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setFlexibility( ::sal_Int32 i_value ) throw (IllegalArgumentException, RuntimeException)
+ {
+ if ( i_value < 0 )
+ throw IllegalArgumentException( ::rtl::OUString(), *this, 1 );
+ impl_set( m_nFlexibility, i_value, "Flexibility" );
+ }
-void SAL_CALL GridColumn::setHorizontalAlign(HorizontalAlignment align) throw (::com::sun::star::uno::RuntimeException)
-{
- horizontalAlign = align;
- broadcast_changed(HALIGN, Any(horizontalAlign),Any(align));
-}
-//---------------------------------------------------------------------
-void SAL_CALL GridColumn::addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.addListener( XGridColumnListener::static_type(), xListener );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ HorizontalAlignment SAL_CALL GridColumn::getHorizontalAlign() throw (::com::sun::star::uno::RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_eHorizontalAlign;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setHorizontalAlign(HorizontalAlignment align) throw (::com::sun::star::uno::RuntimeException)
+ {
+ impl_set( m_eHorizontalAlign, align, "HorizontalAlign" );
+ }
-void SAL_CALL GridColumn::removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.removeListener( XGridColumnListener::static_type(), xListener );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::addGridColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException)
+ {
+ rBHelper.addListener( XGridColumnListener::static_type(), xListener );
+ }
-//---------------------------------------------------------------------
-// XComponent
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::removeGridColumnListener( const Reference< XGridColumnListener >& xListener ) throw (RuntimeException)
+ {
+ rBHelper.removeListener( XGridColumnListener::static_type(), xListener );
+ }
-void SAL_CALL GridColumn::dispose() throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::disposing()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aIdentifier.clear();
+ m_sTitle = m_sHelpText = ::rtl::OUString();
+ }
- ::com::sun::star::lang::EventObject aEvent;
- aEvent.Source.set( static_cast< ::cppu::OWeakObject* >( this ) );
- BrdcstHelper.aLC.disposeAndClear( aEvent );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getIndex() throw (RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nIndex;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void GridColumn::setIndex( sal_Int32 const i_index )
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ m_nIndex = i_index;
+ }
-void SAL_CALL GridColumn::addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.addListener( XEventListener::static_type(), xListener );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL GridColumn::getDataColumnIndex() throw(RuntimeException)
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ return m_nDataColumnIndex;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridColumn::setDataColumnIndex( ::sal_Int32 i_dataColumnIndex ) throw(RuntimeException)
+ {
+ impl_set( m_nDataColumnIndex, i_dataColumnIndex, "DataColumnIndex" );
+ }
-void SAL_CALL GridColumn::removeEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException)
-{
- BrdcstHelper.removeListener( XEventListener::static_type(), xListener );
-}
-void SAL_CALL GridColumn::setIndex(sal_Int32 _nIndex) throw (::com::sun::star::uno::RuntimeException)
-{
- index = _nIndex;
-}
-//---------------------------------------------------------------------
-// XServiceInfo
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::rtl::OUString SAL_CALL GridColumn::getImplementationName( ) throw (RuntimeException)
+ {
+ return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "org.openoffice.comp.toolkit.GridColumn" ) );
+ }
-::rtl::OUString SAL_CALL GridColumn::getImplementationName( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aImplName( RTL_CONSTASCII_USTRINGPARAM( "toolkit.GridColumn" ) );
- return aImplName;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Bool SAL_CALL GridColumn::supportsService( const ::rtl::OUString& i_serviceName ) throw (RuntimeException)
+ {
+ const Sequence< ::rtl::OUString > aServiceNames( getSupportedServiceNames() );
+ for ( sal_Int32 i=0; i<aServiceNames.getLength(); ++i )
+ if ( aServiceNames[i] == i_serviceName )
+ return sal_True;
+ return sal_False;
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL GridColumn::getSupportedServiceNames( ) throw (RuntimeException)
+ {
+ const ::rtl::OUString aServiceName( ::rtl::OUString::createFromAscii( szServiceName_GridColumn ) );
+ const Sequence< ::rtl::OUString > aSeq( &aServiceName, 1 );
+ return aSeq;
+ }
-sal_Bool SAL_CALL GridColumn::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- return ServiceName.equalsAscii( szServiceName_GridColumn );
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XCloneable > SAL_CALL GridColumn::createClone( ) throw (RuntimeException)
+ {
+ return new GridColumn( *this );
+ }
-//---------------------------------------------------------------------
+ //------------------------------------------------------------------------------------------------------------------
+ sal_Int64 SAL_CALL GridColumn::getSomething( const Sequence< sal_Int8 >& i_identifier ) throw(RuntimeException)
+ {
+ if ( ( i_identifier.getLength() == 16 ) && ( i_identifier == getUnoTunnelId() ) )
+ return ::sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ) );
+ return 0;
+ }
-::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL GridColumn::getSupportedServiceNames( ) throw (RuntimeException)
-{
- ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
- static const OUString aServiceName( OUString::createFromAscii( szServiceName_GridColumn ) );
- static const Sequence< OUString > aSeq( &aServiceName, 1 );
- return aSeq;
-}
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< sal_Int8 > GridColumn::getUnoTunnelId() throw()
+ {
+ static ::cppu::OImplementationId const aId;
+ return aId.getImplementationId();
+ }
+ //------------------------------------------------------------------------------------------------------------------
+ GridColumn* GridColumn::getImplementation( const Reference< XInterface >& i_component )
+ {
+ Reference< XUnoTunnel > const xTunnel( i_component, UNO_QUERY );
+ if ( xTunnel.is() )
+ return reinterpret_cast< GridColumn* >( ::sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething( getUnoTunnelId() ) ) );
+ return NULL;
+ }
}
-Reference< XInterface > SAL_CALL GridColumn_CreateInstance( const Reference< XMultiServiceFactory >& )
+::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 >& )
{
- return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::GridColumn );
+ return *( new ::toolkit::GridColumn );
}
diff --git a/toolkit/source/controls/grid/gridcolumn.hxx b/toolkit/source/controls/grid/gridcolumn.hxx
index 38d43d55a07b..b1be836a3862 100644
--- a/toolkit/source/controls/grid/gridcolumn.hxx
+++ b/toolkit/source/controls/grid/gridcolumn.hxx
@@ -25,83 +25,111 @@
*
************************************************************************/
-// MARKER(update_precomp.py): autogen include statement, do not remove
-#include "precompiled_toolkit.hxx"
+
#include <com/sun/star/awt/grid/XGridColumn.hpp>
-#include <com/sun/star/awt/grid/XGridColumnListener.hpp>
-#include <com/sun/star/awt/grid/GridColumnEvent.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
-#include <cppuhelper/implbase2.hxx>
-#include <cppuhelper/implbase3.hxx>
+#include <com/sun/star/style/HorizontalAlignment.hpp>
+
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <comphelper/componentguard.hxx>
#include <rtl/ref.hxx>
-#include <vector>
#include <toolkit/helper/mutexandbroadcasthelper.hxx>
-#include <com/sun/star/style/HorizontalAlignment.hpp>
-using ::rtl::OUString;
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::awt::grid;
-using namespace ::com::sun::star::lang;
+#include <vector>
namespace toolkit
{
-enum broadcast_column_type { column_attribute_changed};
-class GridColumn : public ::cppu::WeakImplHelper2< XGridColumn, XServiceInfo >,
- public MutexAndBroadcastHelper
+typedef ::cppu::WeakComponentImplHelper3 < ::com::sun::star::awt::grid::XGridColumn
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::lang::XUnoTunnel
+ > GridColumn_Base;
+class GridColumn :public ::cppu::BaseMutex
+ ,public GridColumn_Base
{
public:
GridColumn();
+ GridColumn( GridColumn const & i_copySource );
virtual ~GridColumn();
- // XGridColumn
+ // ::com::sun::star::awt::grid::XGridColumn
virtual ::com::sun::star::uno::Any SAL_CALL getIdentifier() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setIdentifier(const ::com::sun::star::uno::Any & value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getColumnWidth() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setColumnWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Int32 SAL_CALL getPreferredWidth() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setPreferredWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getMaxWidth() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setMaxWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Int32 SAL_CALL getMinWidth() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setMinWidth(::sal_Int32 the_value) throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL getResizeable() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setResizeable(::sal_Bool the_value) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getFlexibility() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setFlexibility( ::sal_Int32 _flexibility ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
virtual ::rtl::OUString SAL_CALL getTitle() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setTitle(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::rtl::OUString SAL_CALL getHelpText() throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setHelpText(const ::rtl::OUString & value) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getIndex() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getDataColumnIndex() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL setDataColumnIndex( ::sal_Int32 i_dataColumnIndex ) throw(::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::style::HorizontalAlignment SAL_CALL getHorizontalAlign() throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setHorizontalAlign(::com::sun::star::style::HorizontalAlignment align) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL addColumnListener( const Reference< XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL removeColumnListener( const Reference< XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL updateColumn( const ::rtl::OUString& name, ::sal_Int32 width ) throw (::com::sun::star::uno::RuntimeException);
- // XComponent
- virtual void SAL_CALL dispose( ) throw (RuntimeException);
- virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) throw (RuntimeException);
- virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) throw (RuntimeException);
+ virtual void SAL_CALL addGridColumnListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL removeGridColumnListener( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridColumnListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
+
+ // OComponentHelper
+ virtual void SAL_CALL disposing();
+
+ // XCloneable (base of XGridColumn)
+ 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 (RuntimeException);
- virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
- virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException);
+ 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);
+
+ // XUnoTunnel and friends
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& i_identifier ) throw(::com::sun::star::uno::RuntimeException);
+ static ::com::sun::star::uno::Sequence< sal_Int8 > getUnoTunnelId() throw();
+ static GridColumn* getImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& i_component );
+
+ // attribute access
+ void setIndex( sal_Int32 const i_index );
- virtual void SAL_CALL setIndex(sal_Int32 _nIndex)throw (::com::sun::star::uno::RuntimeException);
private:
- void broadcast( broadcast_column_type eType, const GridColumnEvent& aEvent );
- void broadcast_changed( ::rtl::OUString name, Any oldValue, Any newValue);
-
- Any identifier;
- sal_Int32 index;
- sal_Int32 columnWidth;
- sal_Int32 preferredWidth;
- sal_Int32 maxWidth;
- sal_Int32 minWidth;
- sal_Bool bResizeable;
- ::rtl::OUString title;
- ::com::sun::star::style::HorizontalAlignment horizontalAlign;
+ void broadcast_changed(
+ sal_Char const * const i_asciiAttributeName,
+ ::com::sun::star::uno::Any i_oldValue,
+ ::com::sun::star::uno::Any i_newValue,
+ ::comphelper::ComponentGuard& i_Guard
+ );
+
+ template< class TYPE >
+ void impl_set( TYPE & io_attribute, TYPE const & i_newValue, sal_Char const * i_attributeName )
+ {
+ ::comphelper::ComponentGuard aGuard( *this, rBHelper );
+ if ( io_attribute == i_newValue )
+ return;
+
+ TYPE const aOldValue( io_attribute );
+ io_attribute = i_newValue;
+ broadcast_changed( i_attributeName, ::com::sun::star::uno::makeAny( aOldValue ), ::com::sun::star::uno::makeAny( io_attribute ), aGuard );
+ }
+
+ ::com::sun::star::uno::Any m_aIdentifier;
+ sal_Int32 m_nIndex;
+ sal_Int32 m_nDataColumnIndex;
+ sal_Int32 m_nColumnWidth;
+ sal_Int32 m_nMaxWidth;
+ sal_Int32 m_nMinWidth;
+ sal_Int32 m_nFlexibility;
+ sal_Bool m_bResizeable;
+ ::rtl::OUString m_sTitle;
+ ::rtl::OUString m_sHelpText;
+ ::com::sun::star::style::HorizontalAlignment m_eHorizontalAlign;
};
}
diff --git a/toolkit/source/controls/grid/gridcontrol.cxx b/toolkit/source/controls/grid/gridcontrol.cxx
index 5125c1349ade..acda52753a60 100644
--- a/toolkit/source/controls/grid/gridcontrol.cxx
+++ b/toolkit/source/controls/grid/gridcontrol.cxx
@@ -28,22 +28,27 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_toolkit.hxx"
-#include <gridcontrol.hxx>
+#include "gridcontrol.hxx"
+#include "grideventforwarder.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#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 <com/sun/star/awt/grid/ScrollBarMode.hpp>
#include <toolkit/helper/unopropertyarrayhelper.hxx>
#include <toolkit/helper/property.hxx>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#include <comphelper/processfactory.hxx>
-#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <tools/color.hxx>
using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::awt::grid;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
@@ -52,10 +57,28 @@ using namespace ::com::sun::star::view;
namespace toolkit
{
-// ----------------------------------------------------
-// class UnoGridModel
-// ----------------------------------------------------
-UnoGridModel::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 )
{
ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
ImplRegisterProperty( BASEPROPERTY_BORDER );
@@ -71,36 +94,131 @@ UnoGridModel::UnoGridModel()
ImplRegisterProperty( BASEPROPERTY_VSCROLL );
ImplRegisterProperty( BASEPROPERTY_TABSTOP );
ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER );
+ ImplRegisterProperty( BASEPROPERTY_ROW_HEADER_WIDTH );
ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER );
- ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL );
- ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL );
+ ImplRegisterProperty( BASEPROPERTY_COLUMN_HEADER_HEIGHT );
+ ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT );
+ 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 );
ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
- ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
- ImplRegisterProperty( BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND );
- ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND );
+ ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
+ ImplRegisterProperty( BASEPROPERTY_USE_GRID_LINES );
ImplRegisterProperty( BASEPROPERTY_GRID_LINE_COLOR );
- ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND );
+ ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND );
+ ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_TEXT_COLOR );
+ ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS );
+ ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
}
+//----------------------------------------------------------------------------------------------------------------------
UnoGridModel::UnoGridModel( const UnoGridModel& rModel )
-: UnoControlModel( rModel )
+ :UnoControlModel( rModel )
{
+ osl_incrementInterlockedCount( &m_refCount );
+ {
+ Reference< XGridDataModel > xDataModel;
+ // clone the data model
+ const Reference< XFastPropertySet > xCloneSource( &const_cast< UnoGridModel& >( rModel ) );
+ try
+ {
+ const Reference< XCloneable > xCloneable( xCloneSource->getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ), UNO_QUERY_THROW );
+ xDataModel.set( xCloneable->createClone(), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ if ( !xDataModel.is() )
+ xDataModel = lcl_getDefaultDataModel_throw( maContext );
+ UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_DATAMODEL, makeAny( xDataModel ) );
+ // do *not* use setFastPropertyValue here: The UnoControlModel ctor did a simple copy of all property values,
+ // so before this call here, we share our data model with the own of the clone source. setFastPropertyValue,
+ // then, disposes the old data model - which means the data model which in fact belongs to the clone source.
+ // so, call the UnoControlModel's impl-method for setting the value.
+
+ // clone the column model
+ Reference< XGridColumnModel > xColumnModel;
+ try
+ {
+ const Reference< XCloneable > xCloneable( xCloneSource->getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL ), UNO_QUERY_THROW );
+ xColumnModel.set( xCloneable->createClone(), UNO_QUERY_THROW );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ if ( !xColumnModel.is() )
+ xColumnModel = lcl_getDefaultColumnModel_throw( maContext );
+ UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( xColumnModel ) );
+ // same comment as above: do not use our own setPropertyValue here.
+ }
+ osl_decrementInterlockedCount( &m_refCount );
}
+//----------------------------------------------------------------------------------------------------------------------
UnoControlModel* UnoGridModel::Clone() const
{
return new UnoGridModel( *this );
}
+//----------------------------------------------------------------------------------------------------------------------
+namespace
+{
+ void lcl_dispose_nothrow( const Any& i_component )
+ {
+ try
+ {
+ const Reference< XComponent > xComponent( i_component, UNO_QUERY_THROW );
+ xComponent->dispose();
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+}
+
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridModel::dispose( ) throw(RuntimeException)
+{
+ lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL ) );
+ lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ) );
+
+ UnoControlModel::dispose();
+}
+
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception)
+{
+ Any aOldSubModel;
+ if ( ( nHandle == BASEPROPERTY_GRID_COLUMNMODEL ) || ( nHandle == BASEPROPERTY_GRID_DATAMODEL ) )
+ {
+ aOldSubModel = getFastPropertyValue( nHandle );
+ if ( aOldSubModel == rValue )
+ {
+ OSL_ENSURE( false, "UnoGridModel::setFastPropertyValue_NoBroadcast: setting the same value, again!" );
+ // shouldn't this have been caught by convertFastPropertyValue?
+ aOldSubModel.clear();
+ }
+ }
+
+ UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
+
+ if ( aOldSubModel.hasValue() )
+ lcl_dispose_nothrow( aOldSubModel );
+}
+
+//----------------------------------------------------------------------------------------------------------------------
OUString UnoGridModel::getServiceName() throw(RuntimeException)
{
return OUString::createFromAscii( szServiceName_GridControlModel );
}
+//----------------------------------------------------------------------------------------------------------------------
Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
{
switch( nPropId )
@@ -110,27 +228,26 @@ Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
case BASEPROPERTY_GRID_SELECTIONMODE:
return uno::makeAny( SelectionType(1) );
case BASEPROPERTY_GRID_SHOWROWHEADER:
+ case BASEPROPERTY_USE_GRID_LINES:
return uno::makeAny( (sal_Bool)sal_False );
+ case BASEPROPERTY_ROW_HEADER_WIDTH:
+ return uno::makeAny( sal_Int32( 10 ) );
case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
- return uno::makeAny( (sal_Bool)sal_False );
- case BASEPROPERTY_GRID_DATAMODEL:
- return uno::makeAny( Reference<XGridDataModel> ());
- case BASEPROPERTY_GRID_COLUMNMODEL:
- return uno::makeAny(Reference<XGridColumnModel>() );
- case BASEPROPERTY_GRID_EVEN_ROW_BACKGROUND:
- return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) );
+ return uno::makeAny( (sal_Bool)sal_True );
+ case BASEPROPERTY_COLUMN_HEADER_HEIGHT:
+ case BASEPROPERTY_ROW_HEIGHT:
case BASEPROPERTY_GRID_HEADER_BACKGROUND:
- return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) );
+ case BASEPROPERTY_GRID_HEADER_TEXT_COLOR:
case BASEPROPERTY_GRID_LINE_COLOR:
- return uno::makeAny( com::sun::star::util::Color(0xFFFFFF) );
- case BASEPROPERTY_GRID_ROW_BACKGROUND:
- return uno::makeAny(com::sun::star::util::Color(0xFFFFFF) );
+ case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS:
+ return Any();
default:
return UnoControlModel::ImplGetDefaultValue( nPropId );
}
}
+//----------------------------------------------------------------------------------------------------------------------
::cppu::IPropertyArrayHelper& UnoGridModel::getInfoHelper()
{
static UnoPropertyArrayHelper* pHelper = NULL;
@@ -142,6 +259,7 @@ Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
return *pHelper;
}
+//----------------------------------------------------------------------------------------------------------------------
// XMultiPropertySet
Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( ) throw(RuntimeException)
{
@@ -150,20 +268,29 @@ Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( ) throw(Runtime
}
-// ----------------------------------------------------
-// class UnoGridControl
-// ----------------------------------------------------
-UnoGridControl::UnoGridControl()
-: mSelectionMode(SelectionType(1)),
- m_aSelectionListeners( *this )
+//======================================================================================================================
+//= UnoGridControl
+//======================================================================================================================
+UnoGridControl::UnoGridControl( const Reference< XMultiServiceFactory >& i_factory )
+ :UnoGridControl_Base( i_factory )
+ ,mSelectionMode(SelectionType(1))
+ ,m_aSelectionListeners( *this )
+ ,m_pEventForwarder( new GridEventForwarder( *this ) )
+{
+}
+
+//----------------------------------------------------------------------------------------------------------------------
+UnoGridControl::~UnoGridControl()
{
}
+//----------------------------------------------------------------------------------------------------------------------
OUString UnoGridControl::GetComponentServiceName()
{
return OUString::createFromAscii( "Grid" );
}
+//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::dispose( ) throw(RuntimeException)
{
lang::EventObject aEvt;
@@ -172,113 +299,155 @@ void SAL_CALL UnoGridControl::dispose( ) throw(RuntimeException)
UnoControl::dispose();
}
-void UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException)
{
UnoControlBase::createPeer( rxToolkit, rParentPeer );
- Reference< XGridControl > xGrid( getPeer(), UNO_QUERY_THROW );
+ const Reference< XGridControl > xGrid( getPeer(), UNO_QUERY_THROW );
xGrid->addSelectionListener(&m_aSelectionListeners);
+}
- Reference<XGridDataListener> xListener ( getPeer(), UNO_QUERY_THROW );
- Reference<XGridColumnListener> xColListener ( getPeer(), UNO_QUERY_THROW );
- Reference<XPropertySet> xPropSet ( getModel(), UNO_QUERY_THROW );
-
- Reference<XGridDataModel> xGridDataModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "GridDataModel" )), UNO_QUERY_THROW );
- if(xGridDataModel != NULL)
- xGridDataModel->addDataListener(xListener);
- Reference<XGridColumnModel> xGridColumnModel ( xPropSet->getPropertyValue(OUString::createFromAscii( "ColumnModel" )), UNO_QUERY_THROW );
- if(xGridColumnModel != NULL)
+//----------------------------------------------------------------------------------------------------------------------
+namespace
+{
+ void lcl_setEventForwarding( const Reference< XControlModel >& i_gridControlModel, const ::boost::scoped_ptr< GridEventForwarder >& i_listener,
+ bool const i_add )
{
- for(int i = 0;i<xGridColumnModel->getColumnCount();i++)
+ const Reference< XPropertySet > xModelProps( i_gridControlModel, UNO_QUERY );
+ if ( !xModelProps.is() )
+ return;
+
+ try
{
- xGridColumnModel->getColumn(i)->addColumnListener(xColListener);
+ Reference< XContainer > const xColModel(
+ xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnModel" ) ) ),
+ UNO_QUERY_THROW );
+ if ( i_add )
+ xColModel->addContainerListener( i_listener.get() );
+ else
+ xColModel->removeContainerListener( i_listener.get() );
+
+ Reference< XGridDataModel > const xDataModel(
+ xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridDataModel" ) ) ),
+ UNO_QUERY_THROW
+ );
+ Reference< XMutableGridDataModel > const xMutableDataModel( xDataModel, UNO_QUERY );
+ if ( xMutableDataModel.is() )
+ {
+ if ( i_add )
+ xMutableDataModel->addGridDataListener( i_listener.get() );
+ else
+ xMutableDataModel->removeGridDataListener( i_listener.get() );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
}
}
}
+//----------------------------------------------------------------------------------------------------------------------
+sal_Bool SAL_CALL UnoGridControl::setModel( const Reference< XControlModel >& i_model ) throw(RuntimeException)
+{
+ lcl_setEventForwarding( getModel(), m_pEventForwarder, false );
+ if ( !UnoGridControl_Base::setModel( i_model ) )
+ return sal_False;
+ lcl_setEventForwarding( getModel(), m_pEventForwarder, true );
+ return sal_True;
+}
-// -------------------------------------------------------------------
-// XGridControl
-
-::sal_Int32 UnoGridControl::getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+::sal_Int32 UnoGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl > xGrid ( getPeer(), UNO_QUERY_THROW );
- return xGrid->getItemIndexAtPoint( x, y );
+ Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
+ return xGrid->getRowAtPoint( x, y );
}
-void SAL_CALL UnoGridControl::setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+::sal_Int32 UnoGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->setToolTip( text, columns );
+ Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
+ return xGrid->getColumnAtPoint( x, y );
}
-// -------------------------------------------------------------------
-// XGridSelection
-// -------------------------------------------------------------------
-::sal_Int32 SAL_CALL UnoGridControl::getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+::sal_Int32 SAL_CALL UnoGridControl::getCurrentColumn( ) throw (RuntimeException)
{
- return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getMinSelectionIndex();
+ Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
+ return xGrid->getCurrentColumn();
}
-::sal_Int32 SAL_CALL UnoGridControl::getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+::sal_Int32 SAL_CALL UnoGridControl::getCurrentRow( ) throw (RuntimeException)
{
- return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getMaxSelectionIndex();
+ Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
+ return xGrid->getCurrentRow();
}
-void SAL_CALL UnoGridControl::selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException)
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRows( rangeOfRows);
+ Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRow( i_rowIndex );
}
+//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException)
{
Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectAllRows();
}
-void SAL_CALL UnoGridControl::deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException)
+
+//----------------------------------------------------------------------------------------------------------------------
+void SAL_CALL UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException)
{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectRows( rangeOfRows);
+ Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectRow( i_rowIndex );
}
+//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException)
{
Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->deselectAllRows();
}
+
+//----------------------------------------------------------------------------------------------------------------------
::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelection() throw (::com::sun::star::uno::RuntimeException)
{
return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->getSelection();
}
+//----------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL UnoGridControl::isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException)
{
return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectionEmpty();
}
+//----------------------------------------------------------------------------------------------------------------------
::sal_Bool SAL_CALL UnoGridControl::isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException)
{
return Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->isSelectedIndex( index );
}
-void SAL_CALL UnoGridControl::selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException)
-{
- Reference< XGridControl >( getPeer(), UNO_QUERY_THROW )->selectRow( y );
-}
-
+//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
{
m_aSelectionListeners.addInterface( listener );
}
+//----------------------------------------------------------------------------------------------------------------------
void SAL_CALL UnoGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException)
{
m_aSelectionListeners.removeInterface( listener );
}
+
}//namespace toolkit
-Reference< XInterface > SAL_CALL GridControl_CreateInstance( const Reference< XMultiServiceFactory >& )
+Reference< XInterface > SAL_CALL GridControl_CreateInstance( const Reference< XMultiServiceFactory >& i_factory )
{
- return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridControl );
+ return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridControl( i_factory ) );
}
-Reference< XInterface > SAL_CALL GridControlModel_CreateInstance( const Reference< XMultiServiceFactory >& )
+Reference< XInterface > SAL_CALL GridControlModel_CreateInstance( const Reference< XMultiServiceFactory >& i_factory )
{
- return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridModel );
+ return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridModel( i_factory ) );
}
diff --git a/toolkit/source/controls/grid/gridcontrol.hxx b/toolkit/source/controls/grid/gridcontrol.hxx
index 0c8ddb1c02b6..61d9f8fc0232 100644
--- a/toolkit/source/controls/grid/gridcontrol.hxx
+++ b/toolkit/source/controls/grid/gridcontrol.hxx
@@ -30,21 +30,20 @@
#include <com/sun/star/awt/grid/XGridControl.hpp>
#include <com/sun/star/view/SelectionType.hpp>
+
#include <toolkit/controls/unocontrolbase.hxx>
#include <toolkit/controls/unocontrolmodel.hxx>
#include <toolkit/helper/servicenames.hxx>
#include <cppuhelper/implbase1.hxx>
#include <comphelper/sequence.hxx>
-
#include <toolkit/helper/listenermultiplexer.hxx>
-namespace toolkit {
+#include <boost/scoped_ptr.hpp>
+
+namespace toolkit
+{
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::awt;
-using namespace ::com::sun::star::lang;
-using namespace ::com::sun::star::beans;
-using namespace ::com::sun::star::container;
+class GridEventForwarder;
// ===================================================================
// = UnoGridModel
@@ -52,21 +51,27 @@ using namespace ::com::sun::star::container;
class UnoGridModel : public UnoControlModel
{
protected:
- Any ImplGetDefaultValue( sal_uInt16 nPropId ) const;
+ ::com::sun::star::uno::Any ImplGetDefaultValue( sal_uInt16 nPropId ) const;
::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper();
public:
- UnoGridModel();
+ UnoGridModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory );
UnoGridModel( const UnoGridModel& rModel );
UnoControlModel* Clone() const;
+ // ::com::sun::star::lang::XComponent
+ void SAL_CALL dispose( ) throw(::com::sun::star::uno::RuntimeException);
+
// ::com::sun::star::beans::XMultiPropertySet
::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo( ) throw(::com::sun::star::uno::RuntimeException);
// ::com::sun::star::io::XPersistObject
::rtl::OUString SAL_CALL getServiceName() throw(::com::sun::star::uno::RuntimeException);
+ // OPropertySetHelper
+ void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) throw (::com::sun::star::uno::Exception);
+
// XServiceInfo
DECLIMPL_SERVICEINFO_DERIVED( UnoGridModel, UnoControlModel, szServiceName_GridControlModel )
};
@@ -75,10 +80,13 @@ public:
// ===================================================================
// = UnoGridControl
// ===================================================================
-class UnoGridControl : public ::cppu::ImplInheritanceHelper1< UnoControlBase, ::com::sun::star::awt::grid::XGridControl >
+typedef ::cppu::ImplInheritanceHelper1 < UnoControlBase
+ , ::com::sun::star::awt::grid::XGridControl
+ > UnoGridControl_Base;
+class UnoGridControl : public UnoGridControl_Base
{
public:
- UnoGridControl();
+ UnoGridControl( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory );
::rtl::OUString GetComponentServiceName();
// ::com::sun::star::lang::XComponent
@@ -86,24 +94,22 @@ public:
// ::com::sun::star::awt::XControl
void SAL_CALL createPeer( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XToolkit >& Toolkit, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& Parent ) throw(::com::sun::star::uno::RuntimeException);
+ sal_Bool SAL_CALL setModel( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel >& rxModel ) throw(::com::sun::star::uno::RuntimeException);
// ::com::sun::star::awt::grid::XGridControl
-
- virtual ::sal_Int32 SAL_CALL getItemIndexAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL setToolTip(const ::com::sun::star::uno::Sequence< ::rtl::OUString >& text, const ::com::sun::star::uno::Sequence< ::sal_Int32 >& columns) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCurrentColumn( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::sal_Int32 SAL_CALL getCurrentRow( ) throw (::com::sun::star::uno::RuntimeException);
// ::com::sun::star::awt::grid::XGridSelection
-
- virtual ::sal_Int32 SAL_CALL getMinSelectionIndex() throw (::com::sun::star::uno::RuntimeException);
- virtual ::sal_Int32 SAL_CALL getMaxSelectionIndex() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL selectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL selectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL selectAllRows() throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL deselectRows(const ::com::sun::star::uno::Sequence< ::sal_Int32 >& rangeOfRows) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL deselectRow( ::sal_Int32 i_rowIndex ) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL deselectAllRows() throw (::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL getSelection() throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isSelectionEmpty() throw (::com::sun::star::uno::RuntimeException);
virtual ::sal_Bool SAL_CALL isSelectedIndex(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException);
- virtual void SAL_CALL selectRow(::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException);
@@ -111,9 +117,14 @@ public:
DECLIMPL_SERVICEINFO_DERIVED( UnoGridControl, UnoControlBase, szServiceName_GridControl )
using UnoControl::getPeer;
+
+protected:
+ ~UnoGridControl();
+
private:
- ::com::sun::star::view::SelectionType mSelectionMode;
- SelectionListenerMultiplexer m_aSelectionListeners;
+ ::com::sun::star::view::SelectionType mSelectionMode;
+ SelectionListenerMultiplexer m_aSelectionListeners;
+ ::boost::scoped_ptr< GridEventForwarder > m_pEventForwarder;
};
} // toolkit
diff --git a/toolkit/source/controls/grid/grideventforwarder.cxx b/toolkit/source/controls/grid/grideventforwarder.cxx
new file mode 100755
index 000000000000..c3760b8315a3
--- /dev/null
+++ b/toolkit/source/controls/grid/grideventforwarder.cxx
@@ -0,0 +1,149 @@
+/*************************************************************************
+ * 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 "grideventforwarder.hxx"
+#include "gridcontrol.hxx"
+
+/** === begin UNO includes === **/
+/** === end UNO includes === **/
+
+//......................................................................................................................
+namespace toolkit
+{
+//......................................................................................................................
+
+ /** === begin UNO using === **/
+ 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::awt::grid::GridDataEvent;
+ using ::com::sun::star::container::ContainerEvent;
+ using ::com::sun::star::lang::EventObject;
+ /** === end UNO using === **/
+
+ //==================================================================================================================
+ //= GridEventForwarder
+ //==================================================================================================================
+ //------------------------------------------------------------------------------------------------------------------
+ GridEventForwarder::GridEventForwarder( UnoGridControl& i_parent )
+ :m_parent( i_parent )
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ GridEventForwarder::~GridEventForwarder()
+ {
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::acquire() throw()
+ {
+ m_parent.acquire();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::release() throw()
+ {
+ m_parent.release();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XGridDataListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->rowsInserted( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XGridDataListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->rowsRemoved( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XGridDataListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->dataChanged( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XGridDataListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->rowHeadingChanged( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XContainerListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->elementInserted( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XContainerListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->elementRemoved( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException)
+ {
+ Reference< XContainerListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->elementReplaced( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL GridEventForwarder::disposing( const EventObject& i_event ) throw (RuntimeException)
+ {
+ Reference< XEventListener > xPeer( m_parent.getPeer(), UNO_QUERY );
+ if ( xPeer.is() )
+ xPeer->disposing( i_event );
+ }
+
+//......................................................................................................................
+} // namespace toolkit
+//......................................................................................................................
diff --git a/toolkit/source/controls/grid/grideventforwarder.hxx b/toolkit/source/controls/grid/grideventforwarder.hxx
new file mode 100755
index 000000000000..5a8b03f57037
--- /dev/null
+++ b/toolkit/source/controls/grid/grideventforwarder.hxx
@@ -0,0 +1,85 @@
+/*************************************************************************
+ * 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_GRIDEVENTFORWARDER_HXX
+#define TOOLKIT_GRIDEVENTFORWARDER_HXX
+
+/** === begin UNO includes === **/
+#include <com/sun/star/awt/grid/XGridDataListener.hpp>
+#include <com/sun/star/awt/grid/XGridColumnListener.hpp>
+#include <com/sun/star/container/XContainerListener.hpp>
+/** === end UNO includes === **/
+
+#include <cppuhelper/implbase2.hxx>
+
+//......................................................................................................................
+namespace toolkit
+{
+//......................................................................................................................
+
+ class UnoGridControl;
+
+ //==================================================================================================================
+ //= GridEventForwarder
+ //==================================================================================================================
+ typedef ::cppu::ImplHelper2 < ::com::sun::star::awt::grid::XGridDataListener
+ , ::com::sun::star::container::XContainerListener
+ > GridEventForwarder_Base;
+
+ class GridEventForwarder : public GridEventForwarder_Base
+ {
+ public:
+ GridEventForwarder( UnoGridControl& i_parent );
+ virtual ~GridEventForwarder();
+
+ public:
+ // XInterface
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XGridDataListener
+ virtual void SAL_CALL rowsInserted( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowsRemoved( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL dataChanged( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowHeadingChanged( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XContainerListener
+ virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& i_event ) throw (::com::sun::star::uno::RuntimeException);
+
+ private:
+ UnoGridControl& m_parent;
+ };
+
+//......................................................................................................................
+} // namespace toolkit
+//......................................................................................................................
+
+#endif // TOOLKIT_GRIDEVENTFORWARDER_HXX
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/sortablegriddatamodel.cxx b/toolkit/source/controls/grid/sortablegriddatamodel.cxx
new file mode 100755
index 000000000000..77a2ffa1637b
--- /dev/null
+++ b/toolkit/source/controls/grid/sortablegriddatamodel.cxx
@@ -0,0 +1,877 @@
+/*************************************************************************
+ * 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 "toolkit/helper/servicenames.hxx"
+
+/** === begin UNO includes === **/
+#include <com/sun/star/i18n/XCollator.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/ucb/AlreadyInitializedException.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/anycompare.hxx>
+#include <cppuhelper/typeprovider.hxx>
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+#include <vcl/svapp.hxx>
+
+#include <set>
+
+//......................................................................................................................
+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;
+ using ::com::sun::star::awt::grid::GridDataEvent;
+ using ::com::sun::star::lang::EventObject;
+ using ::com::sun::star::ucb::AlreadyInitializedException;
+ /** === end UNO using === **/
+
+#ifdef DBG_UTIL
+ const char* SortableGridDataModel_checkInvariants( const void* _pInstance )
+ {
+ return static_cast< const SortableGridDataModel* >( _pInstance )->checkInvariants();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ const char* SortableGridDataModel::checkInvariants() const
+ {
+ if ( m_publicToPrivateRowIndex.size() != m_privateToPublicRowIndex.size() )
+ return "inconsistent index maps";
+
+ if ( m_delegator.is() )
+ {
+ if ( m_publicToPrivateRowIndex.size() != size_t( m_delegator->getRowCount() ) )
+ return "wrong cached row count";
+ }
+ else
+ {
+ if ( !m_publicToPrivateRowIndex.empty() )
+ return "disposed or not initialized, but having a non-empty map";
+ }
+
+ for ( size_t publicIndex=0; publicIndex<m_publicToPrivateRowIndex.size(); ++publicIndex )
+ {
+ ::sal_Int32 const privateIndex = m_publicToPrivateRowIndex[ publicIndex ];
+ if ( ( privateIndex < 0 ) || ( size_t( privateIndex ) >= m_privateToPublicRowIndex.size() ) )
+ return "invalid cached private index";
+
+ if ( m_privateToPublicRowIndex[ privateIndex ] != sal_Int32( publicIndex ) )
+ return "index map traversal not commutavive";
+ }
+
+ if ( impl_isSorted_nothrow() && m_publicToPrivateRowIndex.empty() )
+ return "sorted, but no row index translation tables";
+
+ if ( !impl_isSorted_nothrow() && !m_publicToPrivateRowIndex.empty() )
+ return "unsorted, but have index translation tables";
+
+ return NULL;
+ }
+#endif
+
+#define DBG_CHECK_ME() \
+ DBG_CHKTHIS( SortableGridDataModel, SortableGridDataModel_checkInvariants )
+
+ //------------------------------------------------------------------------------------------------------------------
+ namespace
+ {
+ template< class STLCONTAINER >
+ static void lcl_clear( STLCONTAINER& i_container )
+ {
+ STLCONTAINER empty;
+ empty.swap( i_container );
+ }
+ }
+
+ //==================================================================================================================
+ //= SortableGridDataModel
+ //==================================================================================================================
+ DBG_NAME( SortableGridDataModel )
+ //------------------------------------------------------------------------------------------------------------------
+ SortableGridDataModel::SortableGridDataModel( Reference< XMultiServiceFactory > const & i_factory )
+ :SortableGridDataModel_Base( m_aMutex )
+ ,SortableGridDataModel_PrivateBase()
+ ,m_context( i_factory )
+ ,m_isInitialized( false )
+ ,m_delegator()
+ ,m_collator()
+ ,m_currentSortColumn( -1 )
+ ,m_sortAscending( true )
+ ,m_publicToPrivateRowIndex()
+ ,m_privateToPublicRowIndex()
+ {
+ DBG_CTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ SortableGridDataModel::SortableGridDataModel( SortableGridDataModel const & i_copySource )
+ :cppu::BaseMutex()
+ ,SortableGridDataModel_Base( m_aMutex )
+ ,SortableGridDataModel_PrivateBase()
+ ,m_context( i_copySource.m_context )
+ ,m_isInitialized( true )
+ ,m_delegator()
+ ,m_collator( i_copySource.m_collator )
+ ,m_currentSortColumn( i_copySource.m_currentSortColumn )
+ ,m_sortAscending( i_copySource.m_sortAscending )
+ ,m_publicToPrivateRowIndex( i_copySource.m_publicToPrivateRowIndex )
+ ,m_privateToPublicRowIndex( i_copySource.m_privateToPublicRowIndex )
+ {
+ DBG_CTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
+
+ 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();
+ }
+
+ DBG_DTOR( SortableGridDataModel, SortableGridDataModel_checkInvariants );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL SortableGridDataModel::queryInterface( const Type& aType ) throw (RuntimeException)
+ {
+ Any aReturn( SortableGridDataModel_Base::queryInterface( aType ) );
+ if ( !aReturn.hasValue() )
+ aReturn = SortableGridDataModel_PrivateBase::queryInterface( aType );
+ return aReturn;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::acquire( ) throw ()
+ {
+ SortableGridDataModel_Base::acquire();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::release( ) throw ()
+ {
+ SortableGridDataModel_Base::release();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< Type > SAL_CALL SortableGridDataModel::getTypes( ) throw (RuntimeException)
+ {
+ return SortableGridDataModel_Base::getTypes();
+ // don't expose the types got via SortableGridDataModel_PrivateBase - they're private, after all
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Sequence< ::sal_Int8 > SAL_CALL SortableGridDataModel::getImplementationId( ) throw (RuntimeException)
+ {
+ static ::cppu::OImplementationId aId;
+ return aId.getImplementationId();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ 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 );
+ DBG_CHECK_ME();
+
+ if ( m_delegator.is() )
+ throw AlreadyInitializedException( ::rtl::OUString(), *this );
+
+ 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 );
+
+ m_delegator = xDelegator;
+ m_collator = xCollator;
+
+ m_delegator->addGridDataListener( this );
+
+ m_isInitialized = true;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ GridDataEvent SortableGridDataModel::impl_createPublicEvent( GridDataEvent const & i_originalEvent ) const
+ {
+ GridDataEvent aEvent( i_originalEvent );
+ aEvent.Source = *const_cast< SortableGridDataModel* >( this );
+ aEvent.FirstRow = impl_getPublicRowIndex_nothrow( aEvent.FirstRow );
+ aEvent.LastRow = impl_getPublicRowIndex_nothrow( aEvent.LastRow );
+ return aEvent;
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SortableGridDataModel::impl_broadcast( void ( SAL_CALL XGridDataListener::*i_listenerMethod )( const GridDataEvent & ),
+ GridDataEvent const & i_publicEvent, MethodGuard& i_instanceLock )
+ {
+ ::cppu::OInterfaceContainerHelper* pListeners = rBHelper.getContainer( XGridDataListener::static_type() );
+ if ( pListeners == NULL )
+ return;
+
+ i_instanceLock.clear();
+ pListeners->notifyEach( i_listenerMethod, i_publicEvent );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ // if the data is not sorted, broadcast the event unchanged
+ if ( !impl_isSorted_nothrow() )
+ {
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
+ impl_broadcast( &XGridDataListener::rowsInserted, aEvent, aGuard );
+ return;
+ }
+
+ bool needReIndex = false;
+ if ( i_event.FirstRow > i_event.LastRow )
+ {
+ OSL_ENSURE( false, "SortableGridDataModel::rowsInserted: invalid event - invalid row indexes!" );
+ needReIndex = true;
+ }
+ else if ( size_t( i_event.FirstRow ) > m_privateToPublicRowIndex.size() )
+ {
+ OSL_ENSURE( false, "SortableGridDataModel::rowsInserted: invalid event - too large row index!" );
+ needReIndex = true;
+ }
+
+ if ( needReIndex )
+ {
+ impl_rebuildIndexesAndNotify( aGuard );
+ return;
+ }
+
+ // we do not insert the new rows into the sort order - if somebody adds rows while we're sorted, s/he has
+ // to resort. Instead, we simply append the rows, no matter where they were inserted in the delegator data
+ // model.
+ sal_Int32 const nPublicFirstRow = sal_Int32( m_privateToPublicRowIndex.size() );
+ sal_Int32 nPublicLastRow = nPublicFirstRow;
+ for ( sal_Int32 newRow = i_event.FirstRow; newRow <= i_event.LastRow; ++newRow, ++nPublicLastRow )
+ {
+ m_privateToPublicRowIndex.push_back( nPublicLastRow );
+ m_publicToPrivateRowIndex.push_back( nPublicLastRow );
+ }
+
+ // broadcast the event
+ GridDataEvent const aEvent( *this, -1, -1, nPublicFirstRow, nPublicLastRow );
+ impl_broadcast( &XGridDataListener::rowsInserted, aEvent, aGuard );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ namespace
+ {
+ void lcl_decrementValuesGreaterThan( ::std::vector< ::sal_Int32 > & io_indexMap, sal_Int32 const i_threshold )
+ {
+ for ( ::std::vector< ::sal_Int32 >::iterator loop = io_indexMap.begin();
+ loop != io_indexMap.end();
+ ++loop
+ )
+ {
+ if ( *loop >= i_threshold )
+ --*loop;
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SortableGridDataModel::impl_rebuildIndexesAndNotify( MethodGuard& i_instanceLock )
+ {
+ OSL_PRECOND( impl_isSorted_nothrow(), "SortableGridDataModel::impl_rebuildIndexesAndNotify: illegal call!" );
+
+ // clear the indexes
+ lcl_clear( m_publicToPrivateRowIndex );
+ lcl_clear( m_privateToPublicRowIndex );
+
+ // broadcast an artificial event, saying that all rows have been removed
+ GridDataEvent const aRemovalEvent( *this, -1, -1, -1, -1 );
+ impl_broadcast( &XGridDataListener::rowsRemoved, aRemovalEvent, i_instanceLock );
+ i_instanceLock.reset();
+
+ // rebuild the index
+ impl_reIndex_nothrow( m_currentSortColumn, m_sortAscending );
+
+ // broadcast an artificial event, saying that n rows have been added
+ GridDataEvent const aAdditionEvent( *this, -1, -1, 0, m_delegator->getRowCount() - 1 );
+ impl_broadcast( &XGridDataListener::rowsInserted, aAdditionEvent, i_instanceLock );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ // if the data is not sorted, broadcast the event unchanged
+ if ( !impl_isSorted_nothrow() )
+ {
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
+ impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
+ return;
+ }
+
+ // if all rows have been removed, also simply multiplex to own listeners
+ if ( i_event.FirstRow < 0 )
+ {
+ lcl_clear( m_publicToPrivateRowIndex );
+ lcl_clear( m_privateToPublicRowIndex );
+ GridDataEvent aEvent( i_event );
+ aEvent.Source = *this;
+ impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
+ return;
+ }
+
+ bool needReIndex = false;
+ if ( i_event.FirstRow != i_event.LastRow )
+ {
+ OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: missing implementation - removal of multiple rows!" );
+ needReIndex = true;
+ }
+ else if ( size_t( i_event.FirstRow ) >= m_privateToPublicRowIndex.size() )
+ {
+ OSL_ENSURE( false, "SortableGridDataModel::rowsRemoved: inconsistent/wrong data!" );
+ needReIndex = true;
+ }
+
+ if ( needReIndex )
+ {
+ impl_rebuildIndexesAndNotify( aGuard );
+ return;
+ }
+
+ // build public event version
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
+
+ // remove the entries from the index maps
+ sal_Int32 const privateIndex = i_event.FirstRow;
+ sal_Int32 const publicIndex = aEvent.FirstRow;
+
+ m_publicToPrivateRowIndex.erase( m_publicToPrivateRowIndex.begin() + publicIndex );
+ m_privateToPublicRowIndex.erase( m_privateToPublicRowIndex.begin() + privateIndex );
+
+ // adjust remaining entries in the index maps
+ lcl_decrementValuesGreaterThan( m_publicToPrivateRowIndex, privateIndex );
+ lcl_decrementValuesGreaterThan( m_privateToPublicRowIndex, publicIndex );
+
+ // broadcast the event
+ impl_broadcast( &XGridDataListener::rowsRemoved, aEvent, aGuard );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
+ impl_broadcast( &XGridDataListener::dataChanged, aEvent, aGuard );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ GridDataEvent const aEvent( impl_createPublicEvent( i_event ) );
+ impl_broadcast( &XGridDataListener::rowHeadingChanged, aEvent, aGuard );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::disposing( const EventObject& i_event ) throw (RuntimeException)
+ {
+ // not interested in
+ OSL_UNUSED( i_event );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ 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 > aPublicToPrivate( 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 );
+ aPublicToPrivate[ 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, m_collator ) );
+ 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( aPublicToPrivate.begin(), aPublicToPrivate.end(), aComparator );
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION();
+ return;
+ }
+
+ // also build the "private to public" mapping
+ ::std::vector< sal_Int32 > aPrivateToPublic( aPublicToPrivate.size() );
+ for ( size_t i=0; i<aPublicToPrivate.size(); ++i )
+ aPrivateToPublic[ aPublicToPrivate[i] ] = i;
+
+ m_publicToPrivateRowIndex.swap( aPublicToPrivate );
+ m_privateToPublicRowIndex.swap( aPrivateToPublic );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::sortByColumn( ::sal_Int32 i_columnIndex, ::sal_Bool i_sortAscending ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ 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;
+
+ impl_broadcast(
+ &XGridDataListener::dataChanged,
+ GridDataEvent( *this, -1, -1, -1, -1 ),
+ aGuard
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::removeColumnSort( ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ lcl_clear( m_publicToPrivateRowIndex );
+ lcl_clear( m_privateToPublicRowIndex );
+
+ m_currentSortColumn = -1;
+ m_sortAscending = sal_True;
+
+ impl_broadcast(
+ &XGridDataListener::dataChanged,
+ GridDataEvent( *this, -1, -1, -1, -1 ),
+ aGuard
+ );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Pair< ::sal_Int32, ::sal_Bool > SAL_CALL SortableGridDataModel::getCurrentSortOrder( ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ 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 );
+ DBG_CHECK_ME();
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ 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 );
+ DBG_CHECK_ME();
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->addRows( i_headings, i_data );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::removeRow( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->removeRow( rowIndex );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::removeAllRows( ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ 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 );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ 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 );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->updateRowData( i_columnIndexes, rowIndex, i_values );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::updateRowHeading( ::sal_Int32 i_rowIndex, const Any& i_heading ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ delegator->updateRowHeading( 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 );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ 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 );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ 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 );
+ DBG_CHECK_ME();
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return delegator->getRowCount();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SAL_CALL SortableGridDataModel::getColumnCount() throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return delegator->getColumnCount();
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL SortableGridDataModel::getCellData( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return 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 );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return delegator->getCellToolTip( i_columnIndex, rowIndex );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Any SAL_CALL SortableGridDataModel::getRowHeading( ::sal_Int32 i_rowIndex ) throw (IndexOutOfBoundsException, RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ ::sal_Int32 const rowIndex = impl_getPrivateRowIndex_throw( i_rowIndex );
+
+ Reference< XMutableGridDataModel > const delegator( m_delegator );
+ aGuard.clear();
+ return delegator->getRowHeading( rowIndex );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ void SAL_CALL SortableGridDataModel::disposing()
+ {
+ m_currentSortColumn = -1;
+
+ Reference< XComponent > const delegatorComponent( m_delegator.get() );
+ m_delegator->removeGridDataListener( this );
+ m_delegator.clear();
+ delegatorComponent->dispose();
+
+ Reference< XComponent > const collatorComponent( m_collator, UNO_QUERY );
+ m_collator.clear();
+ if ( collatorComponent.is() )
+ collatorComponent->dispose();
+
+ lcl_clear( m_publicToPrivateRowIndex );
+ lcl_clear( m_privateToPublicRowIndex );
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ Reference< XCloneable > SAL_CALL SortableGridDataModel::createClone( ) throw (RuntimeException)
+ {
+ MethodGuard aGuard( *this, rBHelper );
+ DBG_CHECK_ME();
+
+ 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_getPrivateRowIndex_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_publicToPrivateRowIndex.size(),
+ "SortableGridDataModel::impl_getPrivateRowIndex_throw: inconsistency!", i_publicRowIndex );
+ // obviously the translation table contains too few elements - it should have exactly |getRowCount()|
+ // elements
+
+ return m_publicToPrivateRowIndex[ i_publicRowIndex ];
+ }
+
+ //------------------------------------------------------------------------------------------------------------------
+ ::sal_Int32 SortableGridDataModel::impl_getPublicRowIndex_nothrow( ::sal_Int32 const i_privateRowIndex ) const
+ {
+ if ( !impl_isSorted_nothrow() )
+ // no need to translate anything
+ return i_privateRowIndex;
+
+ if ( i_privateRowIndex < 0 )
+ return i_privateRowIndex;
+
+ ENSURE_OR_RETURN( size_t( i_privateRowIndex ) < m_privateToPublicRowIndex.size(),
+ "SortableGridDataModel::impl_getPublicRowIndex_nothrow: invalid index!", i_privateRowIndex );
+
+ return m_privateToPublicRowIndex[ i_privateRowIndex ];
+ }
+
+//......................................................................................................................
+} // 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..50f08d3a7113
--- /dev/null
+++ b/toolkit/source/controls/grid/sortablegriddatamodel.hxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ * 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
+
+#include "initguard.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>
+#include <com/sun/star/awt/grid/XGridDataListener.hpp>
+/** === end UNO includes === **/
+
+#include <comphelper/componentcontext.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/implbase1.hxx>
+
+//......................................................................................................................
+namespace toolkit
+{
+//......................................................................................................................
+
+ class SortableGridDataModel;
+ typedef InitGuard< SortableGridDataModel > MethodGuard;
+
+ //==================================================================================================================
+ //= SortableGridDataModel
+ //==================================================================================================================
+ typedef ::cppu::WeakComponentImplHelper3 < ::com::sun::star::awt::grid::XSortableMutableGridDataModel
+ , ::com::sun::star::lang::XServiceInfo
+ , ::com::sun::star::lang::XInitialization
+ > SortableGridDataModel_Base;
+ typedef ::cppu::ImplHelper1 < ::com::sun::star::awt::grid::XGridDataListener
+ > SortableGridDataModel_PrivateBase;
+ class SortableGridDataModel :public ::cppu::BaseMutex
+ ,public SortableGridDataModel_Base
+ ,public SortableGridDataModel_PrivateBase
+ {
+ public:
+ SortableGridDataModel( ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > const & i_factory );
+ SortableGridDataModel( SortableGridDataModel const & i_copySource );
+
+ bool isInitialized() const { return m_isInitialized; }
+
+#ifdef DBG_UTIL
+ const char* checkInvariants() const;
+#endif
+
+ 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 void SAL_CALL removeColumnSort( ) throw (::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 updateRowHeading( ::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);
+
+ // XGridDataListener
+ virtual void SAL_CALL rowsInserted( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowsRemoved( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL dataChanged( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL rowHeadingChanged( const ::com::sun::star::awt::grid::GridDataEvent& Event ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& i_event ) throw (::com::sun::star::uno::RuntimeException);
+
+ // XInterface
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type& aType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire( ) throw ();
+ virtual void SAL_CALL release( ) throw ();
+
+ // XTypeProvider
+ virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( ) throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence< ::sal_Int8 > SAL_CALL getImplementationId( ) throw (::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_getPrivateRowIndex_throw( ::sal_Int32 const i_publicRowIndex ) const;
+
+ /** translates the given private row index to a public one
+ */
+ ::sal_Int32 impl_getPublicRowIndex_nothrow( ::sal_Int32 const i_privateRowIndex ) 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 );
+
+ /** translates the given event, obtained from our delegator, to a version which can be broadcasted to our own
+ clients.
+ */
+ ::com::sun::star::awt::grid::GridDataEvent
+ impl_createPublicEvent( ::com::sun::star::awt::grid::GridDataEvent const & i_originalEvent ) const;
+
+ /** broadcasts the given event to our registered XGridDataListeners
+ */
+ void impl_broadcast(
+ void ( SAL_CALL ::com::sun::star::awt::grid::XGridDataListener::*i_listenerMethod )( const ::com::sun::star::awt::grid::GridDataEvent & ),
+ ::com::sun::star::awt::grid::GridDataEvent const & i_publicEvent,
+ MethodGuard& i_instanceLock
+ );
+
+ /** rebuilds our indexes, notifying row removal and row addition events
+
+ First, a rowsRemoved event is notified to our registered listeners. Then, the index translation tables are
+ rebuilt, and a rowsInserted event is notified.
+
+ Only to be called when we're sorted.
+ */
+ void impl_rebuildIndexesAndNotify( MethodGuard& i_instanceLock );
+
+ 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_publicToPrivateRowIndex;
+ ::std::vector< ::sal_Int32 > m_privateToPublicRowIndex;
+ };
+
+//......................................................................................................................
+} // namespace toolkit
+//......................................................................................................................
+
+#endif // TOOLKIT_SORTABLEGRIDDATAMODEL_HXX