| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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::setEnable( sal_Bool bEnable ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| m_pTableModel->setEnabled( bEnable ); |
| Window * pWindow = GetWindow(); |
| if ( pWindow ) |
| { |
| pWindow->Enable( bEnable, sal_True ); |
| pWindow->EnableInput( bEnable ); |
| pWindow->Invalidate(); |
| } |
| } |
| |
| //---------------------------------------------------------------------------------------------------------------------- |
| 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(); |
| } |
| } |