diff options
Diffstat (limited to 'svtools/source/uno/svtxgridcontrol.cxx')
-rw-r--r-- | svtools/source/uno/svtxgridcontrol.cxx | 905 |
1 files changed, 905 insertions, 0 deletions
diff --git a/svtools/source/uno/svtxgridcontrol.cxx b/svtools/source/uno/svtxgridcontrol.cxx new file mode 100644 index 000000000000..64b8f9241ae0 --- /dev/null +++ b/svtools/source/uno/svtxgridcontrol.cxx @@ -0,0 +1,905 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#include "svtxgridcontrol.hxx" +#include <com/sun/star/view/SelectionType.hpp> +#include "svtools/table/tablecontrolinterface.hxx" +#include "svtools/table/gridtablerenderer.hxx" +#include "svtools/table/tablecontrol.hxx" +#include "unocontroltablemodel.hxx" +#include <comphelper/sequence.hxx> +#include <rtl/ref.hxx> +#include <tools/diagnose_ex.h> +#include <toolkit/helper/property.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <comphelper/processfactory.hxx> +#include <com/sun/star/awt/grid/XGridColumn.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/grid/GridInvalidDataException.hpp> +#include <com/sun/star/awt/grid/GridInvalidModelException.hpp> +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <com/sun/star/util/Color.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> + +/** === begin UNO using === **/ +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::makeAny; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::awt::grid::XGridSelectionListener; +using ::com::sun::star::style::VerticalAlignment; +using ::com::sun::star::style::VerticalAlignment_TOP; +using ::com::sun::star::view::SelectionType; +using ::com::sun::star::view::SelectionType_NONE; +using ::com::sun::star::view::SelectionType_RANGE; +using ::com::sun::star::view::SelectionType_SINGLE; +using ::com::sun::star::view::SelectionType_MULTI; +using ::com::sun::star::awt::grid::XGridDataModel; +using ::com::sun::star::awt::grid::GridInvalidDataException; +using ::com::sun::star::lang::EventObject; +using ::com::sun::star::lang::IndexOutOfBoundsException; +using ::com::sun::star::awt::grid::XGridColumnModel; +using ::com::sun::star::awt::grid::GridSelectionEvent; +using ::com::sun::star::awt::grid::XGridColumn; +using ::com::sun::star::container::ContainerEvent; +using ::com::sun::star::awt::grid::GridDataEvent; +using ::com::sun::star::awt::grid::GridInvalidModelException; +using ::com::sun::star::util::VetoException; +/** === end UNO using === **/ + +namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId; +namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType; + +using namespace ::svt::table; + +typedef ::com::sun::star::util::Color UnoColor; + +// --------------------------------------------------------------------------------------------------------------------- +SVTXGridControl::SVTXGridControl() + :m_pTableModel( new UnoControlTableModel() ) + ,m_bTableModelInitCompleted( false ) + ,m_aSelectionListeners( *this ) +{ +} + +// --------------------------------------------------------------------------------------------------------------------- +SVTXGridControl::~SVTXGridControl() +{ +} + +// --------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::SetWindow( Window* pWindow ) +{ + SVTXGridControl_Base::SetWindow( pWindow ); + impl_checkTableModelInit(); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const +{ + if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) ) + throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) ); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const +{ + if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) ) + throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) ); +} + +// --------------------------------------------------------------------------------------------------------------------- +sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 ); + + TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); + return ( tableCell.nRow >= 0 ) ? tableCell.nRow : -1; +} + +// --------------------------------------------------------------------------------------------------------------------- +sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 ); + + TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) ); + return ( tableCell.nColumn >= 0 ) ? tableCell.nColumn : -1; +} + +// --------------------------------------------------------------------------------------------------------------------- +sal_Int32 SAL_CALL SVTXGridControl::getCurrentColumn( ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 ); + + sal_Int32 const nColumn = pTable->GetCurrentColumn(); + return ( nColumn >= 0 ) ? nColumn : -1; +} + +// --------------------------------------------------------------------------------------------------------------------- +sal_Int32 SAL_CALL SVTXGridControl::getCurrentRow( ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 ); + + sal_Int32 const nRow = pTable->GetCurrentRow(); + return ( nRow >= 0 ) ? nRow : -1; +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!" ); + + impl_checkColumnIndex_throw( *pTable, i_columnIndex ); + impl_checkRowIndex_throw( *pTable, i_rowIndex ); + + pTable->GoTo( i_columnIndex, i_rowIndex ); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException) +{ + m_aSelectionListeners.addInterface(listener); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException) +{ + m_aSelectionListeners.removeInterface(listener); +} + +// --------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::setProperty: no control (anymore)!" ); + + switch( GetPropertyId( PropertyName ) ) + { + case BASEPROPERTY_ROW_HEADER_WIDTH: + { + sal_Int32 rowHeaderWidth( -1 ); + aValue >>= rowHeaderWidth; + ENSURE_OR_BREAK( rowHeaderWidth > 0, "SVTXGridControl::setProperty: illegal row header width!" ); + m_pTableModel->setRowHeaderWidth( rowHeaderWidth ); + // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed + pTable->Invalidate(); + } + break; + + case BASEPROPERTY_COLUMN_HEADER_HEIGHT: + { + sal_Int32 columnHeaderHeight = 0; + if ( !aValue.hasValue() ) + { + columnHeaderHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height(); + } + else + { + aValue >>= columnHeaderHeight; + } + ENSURE_OR_BREAK( columnHeaderHeight > 0, "SVTXGridControl::setProperty: illegal column header height!" ); + m_pTableModel->setColumnHeaderHeight( columnHeaderHeight ); + // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed + pTable->Invalidate(); + } + break; + + case BASEPROPERTY_USE_GRID_LINES: + { + GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( + m_pTableModel->getRenderer().get() ); + ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" ); + sal_Bool bUseGridLines = sal_False; + OSL_VERIFY( aValue >>= bUseGridLines ); + pGridRenderer->useGridLines( bUseGridLines ); + pTable->Invalidate(); + } + break; + + case BASEPROPERTY_ROW_HEIGHT: + { + sal_Int32 rowHeight = 0; + if ( !aValue.hasValue() ) + { + rowHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height(); + } + else + { + aValue >>= rowHeight; + } + m_pTableModel->setRowHeight( rowHeight ); + ENSURE_OR_BREAK( rowHeight > 0, "SVTXGridControl::setProperty: illegal row height!" ); + // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed + pTable->Invalidate(); + } + break; + + case BASEPROPERTY_BACKGROUNDCOLOR: + { + // let the base class handle this for the TableControl + VCLXWindow::setProperty( PropertyName, aValue ); + // and forward to the grid control's data window + if ( pTable->IsBackground() ) + pTable->getDataWindow().SetBackground( pTable->GetBackground() ); + else + pTable->getDataWindow().SetBackground(); + } + break; + + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + if( aValue >>= eSelectionType ) + { + SelectionMode eSelMode; + switch( eSelectionType ) + { + case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; + case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; + case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; + default: eSelMode = NO_SELECTION; break; + } + if( pTable->getSelEngine()->GetSelectionMode() != eSelMode ) + pTable->getSelEngine()->SetSelectionMode( eSelMode ); + } + break; + } + case BASEPROPERTY_HSCROLL: + { + sal_Bool bHScroll = true; + if( aValue >>= bHScroll ) + m_pTableModel->setHorizontalScrollbarVisibility( bHScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); + break; + } + + case BASEPROPERTY_VSCROLL: + { + sal_Bool bVScroll = true; + if( aValue >>= bVScroll ) + { + m_pTableModel->setVerticalScrollbarVisibility( bVScroll ? ScrollbarShowAlways : ScrollbarShowSmart ); + } + break; + } + + case BASEPROPERTY_GRID_SHOWROWHEADER: + { + sal_Bool rowHeader = true; + if( aValue >>= rowHeader ) + { + m_pTableModel->setRowHeaders(rowHeader); + } + break; + } + + case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: + m_pTableModel->setRowBackgroundColors( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_GRID_LINE_COLOR: + m_pTableModel->setLineColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_GRID_HEADER_BACKGROUND: + m_pTableModel->setHeaderBackgroundColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: + m_pTableModel->setHeaderTextColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: + m_pTableModel->setActiveSelectionBackColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: + m_pTableModel->setInactiveSelectionBackColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: + m_pTableModel->setActiveSelectionTextColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: + m_pTableModel->setInactiveSelectionTextColor( aValue ); + pTable->Invalidate(); + break; + + + case BASEPROPERTY_TEXTCOLOR: + m_pTableModel->setTextColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_TEXTLINECOLOR: + m_pTableModel->setTextLineColor( aValue ); + pTable->Invalidate(); + break; + + case BASEPROPERTY_VERTICALALIGN: + { + VerticalAlignment eAlign( VerticalAlignment_TOP ); + if ( aValue >>= eAlign ) + m_pTableModel->setVerticalAlign( eAlign ); + break; + } + + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + { + sal_Bool colHeader = true; + if( aValue >>= colHeader ) + { + m_pTableModel->setColumnHeaders(colHeader); + } + break; + } + case BASEPROPERTY_GRID_DATAMODEL: + { + Reference< XGridDataModel > const xDataModel( aValue, UNO_QUERY ); + if ( !xDataModel.is() ) + throw GridInvalidDataException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid data model." ) ), *this ); + + m_pTableModel->setDataModel( xDataModel ); + impl_checkTableModelInit(); + } + break; + + case BASEPROPERTY_GRID_COLUMNMODEL: + { + // obtain new col model + Reference< XGridColumnModel > const xColumnModel( aValue, UNO_QUERY ); + if ( !xColumnModel.is() ) + throw GridInvalidModelException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid column model." ) ), *this ); + + // remove all old columns + m_pTableModel->removeAllColumns(); + + // announce to the TableModel + m_pTableModel->setColumnModel( xColumnModel ); + impl_checkTableModelInit(); + + // add new columns + impl_updateColumnsFromModel_nothrow(); + break; + } + default: + VCLXWindow::setProperty( PropertyName, aValue ); + break; + } +} + + +void SVTXGridControl::impl_checkTableModelInit() +{ + if ( !m_bTableModelInitCompleted && m_pTableModel->hasColumnModel() && m_pTableModel->hasDataModel() ) + { + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + if ( pTable ) + { + pTable->SetModel( PTableModel( m_pTableModel ) ); + + m_bTableModelInitCompleted = true; + + // ensure default columns exist, if they have not previously been added + Reference< XGridDataModel > const xDataModel( m_pTableModel->getDataModel(), UNO_QUERY_THROW ); + Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel(), UNO_QUERY_THROW ); + + sal_Int32 const nDataColumnCount = xDataModel->getColumnCount(); + if ( ( nDataColumnCount > 0 ) && ( xColumnModel->getColumnCount() == 0 ) ) + xColumnModel->setDefaultColumns( nDataColumnCount ); + // this will trigger notifications, which in turn will let us update our m_pTableModel + } + } +} + +namespace +{ + void lcl_convertColor( ::boost::optional< ::Color > const & i_color, Any & o_colorValue ) + { + if ( !i_color ) + o_colorValue.clear(); + else + o_colorValue <<= i_color->GetColor(); + } +} + +Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getProperty: no control (anymore)!", Any() ); + + Any aPropertyValue; + + const sal_uInt16 nPropId = GetPropertyId( PropertyName ); + switch(nPropId) + { + case BASEPROPERTY_GRID_SELECTIONMODE: + { + SelectionType eSelectionType; + + SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode(); + switch( eSelMode ) + { + case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; + case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; + case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; + default: eSelectionType = SelectionType_NONE; break; + } + aPropertyValue <<= eSelectionType; + break; + } + + case BASEPROPERTY_GRID_SHOWROWHEADER: + aPropertyValue <<= sal_Bool( m_pTableModel->hasRowHeaders() ); + break; + + case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: + aPropertyValue <<= sal_Bool( m_pTableModel->hasColumnHeaders() ); + break; + + case BASEPROPERTY_GRID_DATAMODEL: + aPropertyValue <<= m_pTableModel->getDataModel(); + break; + + case BASEPROPERTY_GRID_COLUMNMODEL: + aPropertyValue <<= m_pTableModel->getColumnModel(); + break; + + case BASEPROPERTY_HSCROLL: + { + sal_Bool const bHasScrollbar = ( m_pTableModel->getHorizontalScrollbarVisibility() != ScrollbarShowNever ); + aPropertyValue <<= bHasScrollbar; + break; + } + + case BASEPROPERTY_VSCROLL: + { + sal_Bool const bHasScrollbar = ( m_pTableModel->getVerticalScrollbarVisibility() != ScrollbarShowNever ); + aPropertyValue <<= bHasScrollbar; + break; + } + + case BASEPROPERTY_USE_GRID_LINES: + { + GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >( + m_pTableModel->getRenderer().get() ); + ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" ); + aPropertyValue <<= pGridRenderer->useGridLines(); + } + break; + + case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: + { + ::boost::optional< ::std::vector< ::Color > > aColors( m_pTableModel->getRowBackgroundColors() ); + if ( !aColors ) + aPropertyValue.clear(); + else + { + Sequence< UnoColor > aAPIColors( aColors->size() ); + for ( size_t i=0; i<aColors->size(); ++i ) + { + aAPIColors[i] = aColors->at(i).GetColor(); + } + aPropertyValue <<= aAPIColors; + } + } + break; + + case BASEPROPERTY_GRID_LINE_COLOR: + lcl_convertColor( m_pTableModel->getLineColor(), aPropertyValue ); + break; + + case BASEPROPERTY_GRID_HEADER_BACKGROUND: + lcl_convertColor( m_pTableModel->getHeaderBackgroundColor(), aPropertyValue ); + break; + + case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: + lcl_convertColor( m_pTableModel->getHeaderTextColor(), aPropertyValue ); + break; + + case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: + lcl_convertColor( m_pTableModel->getActiveSelectionBackColor(), aPropertyValue ); + break; + + case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: + lcl_convertColor( m_pTableModel->getInactiveSelectionBackColor(), aPropertyValue ); + break; + + case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: + lcl_convertColor( m_pTableModel->getActiveSelectionTextColor(), aPropertyValue ); + break; + + case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: + lcl_convertColor( m_pTableModel->getInactiveSelectionTextColor(), aPropertyValue ); + break; + + case BASEPROPERTY_TEXTCOLOR: + lcl_convertColor( m_pTableModel->getTextColor(), aPropertyValue ); + break; + + case BASEPROPERTY_TEXTLINECOLOR: + lcl_convertColor( m_pTableModel->getTextLineColor(), aPropertyValue ); + break; + + default: + aPropertyValue = VCLXWindow::getProperty( PropertyName ); + break; + } + + return aPropertyValue; +} + +void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds ) +{ + PushPropertyIds( rIds, + BASEPROPERTY_GRID_SHOWROWHEADER, + BASEPROPERTY_GRID_SHOWCOLUMNHEADER, + BASEPROPERTY_GRID_DATAMODEL, + BASEPROPERTY_GRID_COLUMNMODEL, + BASEPROPERTY_GRID_SELECTIONMODE, + BASEPROPERTY_GRID_HEADER_BACKGROUND, + BASEPROPERTY_GRID_HEADER_TEXT_COLOR, + BASEPROPERTY_GRID_LINE_COLOR, + BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS, + BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR, + BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR, + BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR, + BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR, + 0 + ); + VCLXWindow::ImplGetPropertyIds( rIds, true ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + m_pTableModel->notifyRowsInserted( i_event ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL//---------------------------------------------------------------------------------------------------------------------- + SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + m_pTableModel->notifyRowsRemoved( i_event ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + m_pTableModel->notifyDataChanged( i_event ); + + // if the data model is sortable, a dataChanged event is also fired in case the sort order changed. + // So, just in case, invalidate the column header area, too. + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::dataChanged: no control (anymore)!" ); + pTable->getTableControlInterface().invalidate( TableAreaColumnHeaders ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + OSL_UNUSED( i_event ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" ); + + // TODO: we could do better than this - invalidate the header area only + pTable->getTableControlInterface().invalidate( TableAreaRowHeaders ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + Reference< XGridColumn > const xGridColumn( i_event.Element, UNO_QUERY_THROW ); + + sal_Int32 nIndex( m_pTableModel->getColumnCount() ); + OSL_VERIFY( i_event.Accessor >>= nIndex ); + m_pTableModel->insertColumn( nIndex, xGridColumn ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + sal_Int32 nIndex( -1 ); + OSL_VERIFY( i_event.Accessor >>= nIndex ); + m_pTableModel->removeColumn( nIndex ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException) +{ + OSL_ENSURE( false, "SVTXGridControl::elementReplaced: not implemented!" ); + // at the moment, the XGridColumnModel API does not allow replacing columns + OSL_UNUSED( i_event ); + // TODO: replace the respective column in our table model +} + + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::disposing( const EventObject& Source ) throw(RuntimeException) +{ + VCLXWindow::disposing( Source ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" ); + + impl_checkRowIndex_throw( *pTable, i_rowIndex ); + + pTable->SelectRow( i_rowIndex, true ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::selectAllRows() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectAllRows: no control (anymore)!" ); + + pTable->SelectAllRows( true ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" ); + + impl_checkRowIndex_throw( *pTable, i_rowIndex ); + + pTable->SelectRow( i_rowIndex, false ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SAL_CALL SVTXGridControl::deselectAllRows() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectAllRows: no control (anymore)!" ); + + pTable->SelectAllRows( false ); +} + +//---------------------------------------------------------------------------------------------------------------------- +Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() ); + + sal_Int32 selectionCount = pTable->GetSelectedRowCount(); + Sequence< sal_Int32 > selectedRows( selectionCount ); + for ( sal_Int32 i=0; i<selectionCount; ++i ) + selectedRows[i] = pTable->GetSelectedRowIndex(i); + return selectedRows; +} + +//---------------------------------------------------------------------------------------------------------------------- +::sal_Bool SAL_CALL SVTXGridControl::hasSelectedRows() throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", sal_True ); + + return pTable->GetSelectedRowCount() > 0; +} + +//---------------------------------------------------------------------------------------------------------------------- +::sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", sal_False ); + + return pTable->IsRowSelected( index ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::dispose() throw(RuntimeException) +{ + EventObject aObj; + aObj.Source = (::cppu::OWeakObject*)this; + m_aSelectionListeners.disposeAndClear( aObj ); + VCLXWindow::dispose(); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + ::vos::OGuard aGuard( GetMutex() ); + + Reference< XWindow > xKeepAlive( this ); + + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" ); + + bool handled = false; + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_TABLEROW_SELECT: + { + if ( m_aSelectionListeners.getLength() ) + ImplCallItemListeners(); + handled = true; + } + break; + + case VCLEVENT_CONTROL_GETFOCUS: + { + // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also + // works when the control is used outside the UNO context + if ( pTable->GetRowCount()>0 ) + { + pTable->commitCellEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + makeAny( AccessibleStateType::FOCUSED ), + Any() + ); + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, + Any(), + Any() + ); + } + else + { + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + makeAny( AccessibleStateType::FOCUSED ), + Any() + ); + } + } + break; + + case VCLEVENT_CONTROL_LOSEFOCUS: + { + // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also + // works when the control is used outside the UNO context + if ( pTable->GetRowCount()>0 ) + { + pTable->commitCellEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + Any(), + makeAny( AccessibleStateType::FOCUSED ) + ); + } + else + { + pTable->commitTableEventIfAccessibleAlive( + AccessibleEventId::STATE_CHANGED, + Any(), + makeAny( AccessibleStateType::FOCUSED ) + ); + } + } + break; + } + + if ( !handled ) + VCLXWindow::ProcessWindowEvent( rVclWindowEvent ); +} + +//---------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::ImplCallItemListeners() +{ + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" ); + + if ( m_aSelectionListeners.getLength() ) + { + GridSelectionEvent aEvent; + aEvent.Source = (::cppu::OWeakObject*)this; + + sal_Int32 const nSelectedRowCount( pTable->GetSelectedRowCount() ); + aEvent.SelectedRowIndexes.realloc( nSelectedRowCount ); + for ( sal_Int32 i=0; i<nSelectedRowCount; ++i ) + aEvent.SelectedRowIndexes[i] = pTable->GetSelectedRowIndex( i ); + m_aSelectionListeners.selectionChanged( aEvent ); + } +} + +//---------------------------------------------------------------------------------------------------------------------- +void SVTXGridControl::impl_updateColumnsFromModel_nothrow() +{ + Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel() ); + ENSURE_OR_RETURN_VOID( xColumnModel.is(), "no model!" ); + TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() ); + ENSURE_OR_RETURN_VOID( pTable != NULL, "no table!" ); + + try + { + const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns(); + for ( const Reference< XGridColumn >* colRef = columns.getConstArray(); + colRef != columns.getConstArray() + columns.getLength(); + ++colRef + ) + { + ENSURE_OR_CONTINUE( colRef->is(), "illegal column!" ); + + m_pTableModel->appendColumn( *colRef ); + } + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } +} |