1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <awt/vclxwindows.hxx>
21 #include <cppuhelper/implbase.hxx>
22 #include <toolkit/helper/listenermultiplexer.hxx>
23 #include <com/sun/star/view/SelectionType.hpp>
24 #include <controls/table/tablecontrol.hxx>
25 #include <controls/table/tablecontrolinterface.hxx>
26 #include <controls/table/gridtablerenderer.hxx>
27 #include "unocontroltablemodel.hxx"
28 #include <sal/log.hxx>
29 #include <comphelper/diagnose_ex.hxx>
30 #include <helper/property.hxx>
31 #include <com/sun/star/awt/grid/XGridColumn.hpp>
32 #include <com/sun/star/awt/grid/GridInvalidDataException.hpp>
33 #include <com/sun/star/awt/grid/GridInvalidModelException.hpp>
34 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
35 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
36 #include <com/sun/star/util/Color.hpp>
37 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <vcl/svapp.hxx>
43 using css::uno::Reference
;
44 using css::uno::Exception
;
45 using css::uno::UNO_QUERY
;
46 using css::uno::UNO_QUERY_THROW
;
48 using css::uno::Sequence
;
49 using css::awt::grid::XGridSelectionListener
;
50 using css::style::VerticalAlignment
;
51 using css::style::VerticalAlignment_TOP
;
52 using css::view::SelectionType
;
53 using css::view::SelectionType_NONE
;
54 using css::view::SelectionType_RANGE
;
55 using css::view::SelectionType_SINGLE
;
56 using css::view::SelectionType_MULTI
;
57 using css::awt::grid::XGridDataModel
;
58 using css::awt::grid::GridInvalidDataException
;
59 using css::lang::EventObject
;
60 using css::lang::IndexOutOfBoundsException
;
61 using css::awt::grid::XGridColumnModel
;
62 using css::awt::grid::GridSelectionEvent
;
63 using css::awt::grid::XGridColumn
;
64 using css::container::ContainerEvent
;
65 using css::awt::grid::GridDataEvent
;
66 using css::awt::grid::GridInvalidModelException
;
68 namespace AccessibleEventId
= css::accessibility::AccessibleEventId
;
69 namespace AccessibleStateType
= css::accessibility::AccessibleStateType
;
71 using namespace ::svt::table
;
74 SVTXGridControl::SVTXGridControl()
75 :m_xTableModel( std::make_shared
<UnoControlTableModel
>() )
76 ,m_bTableModelInitCompleted( false )
77 ,m_aSelectionListeners( *this )
82 SVTXGridControl::~SVTXGridControl()
87 void SVTXGridControl::SetWindow( const VclPtr
< vcl::Window
> &pWindow
)
89 SVTXGridControl_Base::SetWindow( pWindow
);
90 impl_checkTableModelInit();
94 void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl
const & i_table
, sal_Int32
const i_columnIndex
) const
96 if ( ( i_columnIndex
< 0 ) || ( i_columnIndex
>= i_table
.GetColumnCount() ) )
97 throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl
* >( this ) );
101 void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl
const & i_table
, sal_Int32
const i_rowIndex
) const
103 if ( ( i_rowIndex
< 0 ) || ( i_rowIndex
>= i_table
.GetRowCount() ) )
104 throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl
* >( this ) );
108 sal_Int32 SAL_CALL
SVTXGridControl::getRowAtPoint(::sal_Int32 x
, ::sal_Int32 y
)
110 SolarMutexGuard aGuard
;
112 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
113 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 );
115 TableCell
const tableCell
= pTable
->getTableControlInterface().hitTest( Point( x
, y
) );
116 return ( tableCell
.nRow
>= 0 ) ? tableCell
.nRow
: -1;
120 sal_Int32 SAL_CALL
SVTXGridControl::getColumnAtPoint(::sal_Int32 x
, ::sal_Int32 y
)
122 SolarMutexGuard aGuard
;
124 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
125 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 );
127 TableCell
const tableCell
= pTable
->getTableControlInterface().hitTest( Point( x
, y
) );
128 return ( tableCell
.nColumn
>= 0 ) ? tableCell
.nColumn
: -1;
132 sal_Int32 SAL_CALL
SVTXGridControl::getCurrentColumn( )
134 SolarMutexGuard aGuard
;
136 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
137 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 );
139 sal_Int32
const nColumn
= pTable
->GetCurrentColumn();
140 return ( nColumn
>= 0 ) ? nColumn
: -1;
144 sal_Int32 SAL_CALL
SVTXGridControl::getCurrentRow( )
146 SolarMutexGuard aGuard
;
148 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
149 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 );
151 sal_Int32
const nRow
= pTable
->GetCurrentRow();
152 return ( nRow
>= 0 ) ? nRow
: -1;
156 void SAL_CALL
SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
)
158 SolarMutexGuard aGuard
;
160 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
161 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::getCurrentRow: no control (anymore)!" );
163 impl_checkColumnIndex_throw( *pTable
, i_columnIndex
);
164 impl_checkRowIndex_throw( *pTable
, i_rowIndex
);
166 pTable
->GoTo( i_columnIndex
, i_rowIndex
);
170 void SAL_CALL
SVTXGridControl::addSelectionListener(const Reference
< XGridSelectionListener
> & listener
)
172 m_aSelectionListeners
.addInterface(listener
);
176 void SAL_CALL
SVTXGridControl::removeSelectionListener(const Reference
< XGridSelectionListener
> & listener
)
178 m_aSelectionListeners
.removeInterface(listener
);
182 void SVTXGridControl::setProperty( const OUString
& PropertyName
, const Any
& aValue
)
184 SolarMutexGuard aGuard
;
186 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
187 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::setProperty: no control (anymore)!" );
189 switch( GetPropertyId( PropertyName
) )
191 case BASEPROPERTY_ROW_HEADER_WIDTH
:
193 sal_Int32
rowHeaderWidth( -1 );
194 aValue
>>= rowHeaderWidth
;
195 if ( rowHeaderWidth
<= 0 )
197 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row header width!" );
201 m_xTableModel
->setRowHeaderWidth( rowHeaderWidth
);
202 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
203 pTable
->Invalidate();
207 case BASEPROPERTY_COLUMN_HEADER_HEIGHT
:
209 sal_Int32 columnHeaderHeight
= 0;
210 if ( !aValue
.hasValue() )
212 columnHeaderHeight
= pTable
->PixelToLogic(Size(0, pTable
->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont
)).Height();
216 aValue
>>= columnHeaderHeight
;
218 if ( columnHeaderHeight
<= 0 )
220 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal column header width!" );
224 m_xTableModel
->setColumnHeaderHeight( columnHeaderHeight
);
225 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
226 pTable
->Invalidate();
230 case BASEPROPERTY_USE_GRID_LINES
:
232 GridTableRenderer
* pGridRenderer
= dynamic_cast< GridTableRenderer
* >(
233 m_xTableModel
->getRenderer().get() );
234 if ( !pGridRenderer
)
236 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" );
240 bool bUseGridLines
= false;
241 OSL_VERIFY( aValue
>>= bUseGridLines
);
242 pGridRenderer
->useGridLines( bUseGridLines
);
243 pTable
->Invalidate();
247 case BASEPROPERTY_ROW_HEIGHT
:
249 sal_Int32 rowHeight
= 0;
250 if ( !aValue
.hasValue() )
252 rowHeight
= pTable
->PixelToLogic(Size(0, pTable
->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont
)).Height();
256 aValue
>>= rowHeight
;
258 m_xTableModel
->setRowHeight( rowHeight
);
259 if ( rowHeight
<= 0 )
261 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row height!" );
265 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
266 pTable
->Invalidate();
270 case BASEPROPERTY_BACKGROUNDCOLOR
:
272 // let the base class handle this for the TableControl
273 VCLXWindow::setProperty( PropertyName
, aValue
);
274 // and forward to the grid control's data window
275 if ( pTable
->IsBackground() )
276 pTable
->getDataWindow().SetBackground( pTable
->GetBackground() );
278 pTable
->getDataWindow().SetBackground();
282 case BASEPROPERTY_GRID_SELECTIONMODE
:
284 SelectionType eSelectionType
;
285 if( aValue
>>= eSelectionType
)
287 SelectionMode eSelMode
;
288 switch( eSelectionType
)
290 case SelectionType_SINGLE
: eSelMode
= SelectionMode::Single
; break;
291 case SelectionType_RANGE
: eSelMode
= SelectionMode::Range
; break;
292 case SelectionType_MULTI
: eSelMode
= SelectionMode::Multiple
; break;
293 default: eSelMode
= SelectionMode::NONE
; break;
295 if( pTable
->getSelEngine()->GetSelectionMode() != eSelMode
)
296 pTable
->getSelEngine()->SetSelectionMode( eSelMode
);
300 case BASEPROPERTY_HSCROLL
:
302 bool bHScroll
= true;
303 if( aValue
>>= bHScroll
)
304 m_xTableModel
->setHorizontalScrollbarVisibility( bHScroll
? ScrollbarShowAlways
: ScrollbarShowSmart
);
308 case BASEPROPERTY_VSCROLL
:
310 bool bVScroll
= true;
311 if( aValue
>>= bVScroll
)
313 m_xTableModel
->setVerticalScrollbarVisibility( bVScroll
? ScrollbarShowAlways
: ScrollbarShowSmart
);
318 case BASEPROPERTY_GRID_SHOWROWHEADER
:
320 bool rowHeader
= true;
321 if( aValue
>>= rowHeader
)
323 m_xTableModel
->setRowHeaders(rowHeader
);
328 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
:
329 m_xTableModel
->setRowBackgroundColors( aValue
);
330 pTable
->Invalidate();
333 case BASEPROPERTY_GRID_LINE_COLOR
:
334 m_xTableModel
->setLineColor( aValue
);
335 pTable
->Invalidate();
338 case BASEPROPERTY_GRID_HEADER_BACKGROUND
:
339 m_xTableModel
->setHeaderBackgroundColor( aValue
);
340 pTable
->Invalidate();
343 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR
:
344 m_xTableModel
->setHeaderTextColor( aValue
);
345 pTable
->Invalidate();
348 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
:
349 m_xTableModel
->setActiveSelectionBackColor( aValue
);
350 pTable
->Invalidate();
353 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
:
354 m_xTableModel
->setInactiveSelectionBackColor( aValue
);
355 pTable
->Invalidate();
358 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
:
359 m_xTableModel
->setActiveSelectionTextColor( aValue
);
360 pTable
->Invalidate();
363 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
:
364 m_xTableModel
->setInactiveSelectionTextColor( aValue
);
365 pTable
->Invalidate();
369 case BASEPROPERTY_TEXTCOLOR
:
370 m_xTableModel
->setTextColor( aValue
);
371 pTable
->Invalidate();
374 case BASEPROPERTY_TEXTLINECOLOR
:
375 m_xTableModel
->setTextLineColor( aValue
);
376 pTable
->Invalidate();
379 case BASEPROPERTY_VERTICALALIGN
:
381 VerticalAlignment
eAlign( VerticalAlignment_TOP
);
382 if ( aValue
>>= eAlign
)
383 m_xTableModel
->setVerticalAlign( eAlign
);
387 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER
:
389 bool colHeader
= true;
390 if( aValue
>>= colHeader
)
392 m_xTableModel
->setColumnHeaders(colHeader
);
396 case BASEPROPERTY_GRID_DATAMODEL
:
398 Reference
< XGridDataModel
> const xDataModel( aValue
, UNO_QUERY
);
399 if ( !xDataModel
.is() )
400 throw GridInvalidDataException("Invalid data model.", *this );
402 m_xTableModel
->setDataModel( xDataModel
);
403 impl_checkTableModelInit();
407 case BASEPROPERTY_GRID_COLUMNMODEL
:
409 // obtain new col model
410 Reference
< XGridColumnModel
> const xColumnModel( aValue
, UNO_QUERY
);
411 if ( !xColumnModel
.is() )
412 throw GridInvalidModelException("Invalid column model.", *this );
414 // remove all old columns
415 m_xTableModel
->removeAllColumns();
417 // announce to the TableModel
418 m_xTableModel
->setColumnModel( xColumnModel
);
419 impl_checkTableModelInit();
422 impl_updateColumnsFromModel_nothrow();
426 VCLXWindow::setProperty( PropertyName
, aValue
);
432 void SVTXGridControl::impl_checkTableModelInit()
434 if ( !(!m_bTableModelInitCompleted
&& m_xTableModel
->hasColumnModel() && m_xTableModel
->hasDataModel()) )
437 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
441 pTable
->SetModel( PTableModel( m_xTableModel
) );
443 m_bTableModelInitCompleted
= true;
445 // ensure default columns exist, if they have not previously been added
446 Reference
< XGridDataModel
> const xDataModel( m_xTableModel
->getDataModel(), css::uno::UNO_SET_THROW
);
447 Reference
< XGridColumnModel
> const xColumnModel( m_xTableModel
->getColumnModel(), css::uno::UNO_SET_THROW
);
449 sal_Int32
const nDataColumnCount
= xDataModel
->getColumnCount();
450 if ( ( nDataColumnCount
> 0 ) && ( xColumnModel
->getColumnCount() == 0 ) )
451 xColumnModel
->setDefaultColumns( nDataColumnCount
);
452 // this will trigger notifications, which in turn will let us update our m_xTableModel
457 void lcl_convertColor( ::std::optional
< ::Color
> const & i_color
, Any
& o_colorValue
)
460 o_colorValue
.clear();
462 o_colorValue
<<= sal_Int32(*i_color
);
466 Any
SVTXGridControl::getProperty( const OUString
& PropertyName
)
468 SolarMutexGuard aGuard
;
470 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
471 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getProperty: no control (anymore)!", Any() );
475 const sal_uInt16 nPropId
= GetPropertyId( PropertyName
);
478 case BASEPROPERTY_GRID_SELECTIONMODE
:
480 SelectionType eSelectionType
;
482 SelectionMode eSelMode
= pTable
->getSelEngine()->GetSelectionMode();
485 case SelectionMode::Single
: eSelectionType
= SelectionType_SINGLE
; break;
486 case SelectionMode::Range
: eSelectionType
= SelectionType_RANGE
; break;
487 case SelectionMode::Multiple
:eSelectionType
= SelectionType_MULTI
; break;
488 default: eSelectionType
= SelectionType_NONE
; break;
490 aPropertyValue
<<= eSelectionType
;
494 case BASEPROPERTY_GRID_SHOWROWHEADER
:
495 aPropertyValue
<<= m_xTableModel
->hasRowHeaders();
498 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER
:
499 aPropertyValue
<<= m_xTableModel
->hasColumnHeaders();
502 case BASEPROPERTY_GRID_DATAMODEL
:
503 aPropertyValue
<<= m_xTableModel
->getDataModel();
506 case BASEPROPERTY_GRID_COLUMNMODEL
:
507 aPropertyValue
<<= m_xTableModel
->getColumnModel();
510 case BASEPROPERTY_HSCROLL
:
512 bool const bHasScrollbar
= ( m_xTableModel
->getHorizontalScrollbarVisibility() != ScrollbarShowNever
);
513 aPropertyValue
<<= bHasScrollbar
;
517 case BASEPROPERTY_VSCROLL
:
519 bool const bHasScrollbar
= ( m_xTableModel
->getVerticalScrollbarVisibility() != ScrollbarShowNever
);
520 aPropertyValue
<<= bHasScrollbar
;
524 case BASEPROPERTY_USE_GRID_LINES
:
526 GridTableRenderer
* pGridRenderer
= dynamic_cast< GridTableRenderer
* >(
527 m_xTableModel
->getRenderer().get() );
528 if ( !pGridRenderer
)
530 SAL_WARN( "svtools.uno", "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" );
534 aPropertyValue
<<= pGridRenderer
->useGridLines();
538 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
:
540 ::std::optional
< ::std::vector
< ::Color
> > aColors( m_xTableModel
->getRowBackgroundColors() );
542 aPropertyValue
.clear();
545 Sequence
< css::util::Color
> aAPIColors( aColors
->size() );
546 std::transform(aColors
->begin(), aColors
->end(), aAPIColors
.getArray(),
547 [](const auto& color
) { return sal_Int32(color
); });
548 aPropertyValue
<<= aAPIColors
;
553 case BASEPROPERTY_GRID_LINE_COLOR
:
554 lcl_convertColor( m_xTableModel
->getLineColor(), aPropertyValue
);
557 case BASEPROPERTY_GRID_HEADER_BACKGROUND
:
558 lcl_convertColor( m_xTableModel
->getHeaderBackgroundColor(), aPropertyValue
);
561 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR
:
562 lcl_convertColor( m_xTableModel
->getHeaderTextColor(), aPropertyValue
);
565 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
:
566 lcl_convertColor( m_xTableModel
->getActiveSelectionBackColor(), aPropertyValue
);
569 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
:
570 lcl_convertColor( m_xTableModel
->getInactiveSelectionBackColor(), aPropertyValue
);
573 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
:
574 lcl_convertColor( m_xTableModel
->getActiveSelectionTextColor(), aPropertyValue
);
577 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
:
578 lcl_convertColor( m_xTableModel
->getInactiveSelectionTextColor(), aPropertyValue
);
581 case BASEPROPERTY_TEXTCOLOR
:
582 lcl_convertColor( m_xTableModel
->getTextColor(), aPropertyValue
);
585 case BASEPROPERTY_TEXTLINECOLOR
:
586 lcl_convertColor( m_xTableModel
->getTextLineColor(), aPropertyValue
);
590 aPropertyValue
= VCLXWindow::getProperty( PropertyName
);
594 return aPropertyValue
;
598 void SAL_CALL
SVTXGridControl::rowsInserted( const GridDataEvent
& i_event
)
600 SolarMutexGuard aGuard
;
601 m_xTableModel
->notifyRowsInserted( i_event
);
606 SVTXGridControl::rowsRemoved( const GridDataEvent
& i_event
)
608 SolarMutexGuard aGuard
;
609 m_xTableModel
->notifyRowsRemoved( i_event
);
613 void SAL_CALL
SVTXGridControl::dataChanged( const GridDataEvent
& i_event
)
615 SolarMutexGuard aGuard
;
617 m_xTableModel
->notifyDataChanged( i_event
);
619 // if the data model is sortable, a dataChanged event is also fired in case the sort order changed.
620 // So, just in case, invalidate the column header area, too.
621 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
622 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::dataChanged: no control (anymore)!" );
623 pTable
->getTableControlInterface().invalidate( TableArea::ColumnHeaders
);
627 void SAL_CALL
SVTXGridControl::rowHeadingChanged( const GridDataEvent
& )
629 SolarMutexGuard aGuard
;
631 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
632 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" );
634 // TODO: we could do better than this - invalidate the header area only
635 pTable
->getTableControlInterface().invalidate( TableArea::RowHeaders
);
639 void SAL_CALL
SVTXGridControl::elementInserted( const ContainerEvent
& i_event
)
641 SolarMutexGuard aGuard
;
643 Reference
< XGridColumn
> const xGridColumn( i_event
.Element
, UNO_QUERY_THROW
);
645 sal_Int32
nIndex( m_xTableModel
->getColumnCount() );
646 OSL_VERIFY( i_event
.Accessor
>>= nIndex
);
647 m_xTableModel
->insertColumn( nIndex
, xGridColumn
);
651 void SAL_CALL
SVTXGridControl::elementRemoved( const ContainerEvent
& i_event
)
653 SolarMutexGuard aGuard
;
655 sal_Int32
nIndex( -1 );
656 OSL_VERIFY( i_event
.Accessor
>>= nIndex
);
657 m_xTableModel
->removeColumn( nIndex
);
661 void SAL_CALL
SVTXGridControl::elementReplaced( const ContainerEvent
& )
663 OSL_ENSURE( false, "SVTXGridControl::elementReplaced: not implemented!" );
664 // at the moment, the XGridColumnModel API does not allow replacing columns
665 // TODO: replace the respective column in our table model
669 void SAL_CALL
SVTXGridControl::disposing( const EventObject
& Source
)
671 VCLXWindow::disposing( Source
);
675 void SAL_CALL
SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex
)
677 SolarMutexGuard aGuard
;
679 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
680 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::selectRow: no control (anymore)!" );
682 impl_checkRowIndex_throw( *pTable
, i_rowIndex
);
684 pTable
->SelectRow( i_rowIndex
, true );
688 void SAL_CALL
SVTXGridControl::selectAllRows()
690 SolarMutexGuard aGuard
;
692 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
693 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::selectAllRows: no control (anymore)!" );
695 pTable
->SelectAllRows( true );
699 void SAL_CALL
SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex
)
701 SolarMutexGuard aGuard
;
703 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
704 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::deselectRow: no control (anymore)!" );
706 impl_checkRowIndex_throw( *pTable
, i_rowIndex
);
708 pTable
->SelectRow( i_rowIndex
, false );
712 void SAL_CALL
SVTXGridControl::deselectAllRows()
714 SolarMutexGuard aGuard
;
716 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
717 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::deselectAllRows: no control (anymore)!" );
719 pTable
->SelectAllRows( false );
723 Sequence
< ::sal_Int32
> SAL_CALL
SVTXGridControl::getSelectedRows()
725 SolarMutexGuard aGuard
;
727 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
728 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence
< sal_Int32
>() );
730 sal_Int32 selectionCount
= pTable
->GetSelectedRowCount();
731 Sequence
< sal_Int32
> selectedRows( selectionCount
);
732 auto selectedRowsRange
= asNonConstRange(selectedRows
);
733 for ( sal_Int32 i
=0; i
<selectionCount
; ++i
)
734 selectedRowsRange
[i
] = pTable
->GetSelectedRowIndex(i
);
739 sal_Bool SAL_CALL
SVTXGridControl::hasSelectedRows()
741 SolarMutexGuard aGuard
;
743 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
744 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::hasSelectedRows: no control (anymore)!", true );
746 return pTable
->GetSelectedRowCount() > 0;
750 sal_Bool SAL_CALL
SVTXGridControl::isRowSelected( ::sal_Int32 index
)
752 SolarMutexGuard aGuard
;
754 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
755 ENSURE_OR_RETURN( pTable
, "SVTXGridControl::isRowSelected: no control (anymore)!", false );
757 return pTable
->IsRowSelected( index
);
761 void SVTXGridControl::dispose()
764 aObj
.Source
= getXWeak();
765 m_aSelectionListeners
.disposeAndClear( aObj
);
766 VCLXWindow::dispose();
770 void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent
& rVclWindowEvent
)
772 SolarMutexGuard aGuard
;
774 Reference
< XWindow
> xKeepAlive( this );
776 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
777 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" );
779 bool handled
= false;
780 switch ( rVclWindowEvent
.GetId() )
782 case VclEventId::TableRowSelect
:
784 if ( m_aSelectionListeners
.getLength() )
785 ImplCallItemListeners();
790 case VclEventId::ControlGetFocus
:
792 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
793 // works when the control is used outside the UNO context
794 if ( pTable
->GetRowCount()>0 )
796 pTable
->commitCellEventIfAccessibleAlive(
797 AccessibleEventId::STATE_CHANGED
,
798 Any( AccessibleStateType::FOCUSED
),
801 pTable
->commitTableEventIfAccessibleAlive(
802 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED
,
809 pTable
->commitTableEventIfAccessibleAlive(
810 AccessibleEventId::STATE_CHANGED
,
811 Any( AccessibleStateType::FOCUSED
),
818 case VclEventId::ControlLoseFocus
:
820 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
821 // works when the control is used outside the UNO context
822 if ( pTable
->GetRowCount()>0 )
824 pTable
->commitCellEventIfAccessibleAlive(
825 AccessibleEventId::STATE_CHANGED
,
827 Any( AccessibleStateType::FOCUSED
)
832 pTable
->commitTableEventIfAccessibleAlive(
833 AccessibleEventId::STATE_CHANGED
,
835 Any( AccessibleStateType::FOCUSED
)
845 VCLXWindow::ProcessWindowEvent( rVclWindowEvent
);
849 void SVTXGridControl::setEnable( sal_Bool bEnable
)
851 SolarMutexGuard aGuard
;
853 m_xTableModel
->setEnabled( bEnable
);
854 VclPtr
<vcl::Window
> pWindow
= GetWindow();
857 pWindow
->Enable( bEnable
);
858 pWindow
->EnableInput( bEnable
);
859 pWindow
->Invalidate();
864 void SVTXGridControl::ImplCallItemListeners()
866 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
867 ENSURE_OR_RETURN_VOID( pTable
, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" );
869 if ( m_aSelectionListeners
.getLength() )
871 GridSelectionEvent aEvent
;
872 aEvent
.Source
= getXWeak();
874 sal_Int32
const nSelectedRowCount( pTable
->GetSelectedRowCount() );
875 aEvent
.SelectedRowIndexes
.realloc( nSelectedRowCount
);
876 auto pSelectedRowIndexes
= aEvent
.SelectedRowIndexes
.getArray();
877 for ( sal_Int32 i
=0; i
<nSelectedRowCount
; ++i
)
878 pSelectedRowIndexes
[i
] = pTable
->GetSelectedRowIndex( i
);
879 m_aSelectionListeners
.selectionChanged( aEvent
);
884 void SVTXGridControl::impl_updateColumnsFromModel_nothrow()
886 Reference
< XGridColumnModel
> const xColumnModel( m_xTableModel
->getColumnModel() );
887 ENSURE_OR_RETURN_VOID( xColumnModel
.is(), "no model!" );
888 VclPtr
< TableControl
> pTable
= GetAsDynamic
< TableControl
>();
889 ENSURE_OR_RETURN_VOID( pTable
, "no table!" );
893 const Sequence
< Reference
< XGridColumn
> > columns
= xColumnModel
->getColumns();
894 for ( auto const & colRef
: columns
)
898 SAL_WARN( "svtools.uno", "illegal column!" );
902 m_xTableModel
->appendColumn( colRef
);
905 catch( const Exception
& )
907 DBG_UNHANDLED_EXCEPTION("svtools.uno");
911 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */