20#include <awt/vclxwindows.hxx>
23#include <com/sun/star/view/SelectionType.hpp>
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>
43using css::uno::Reference;
44using css::uno::Exception;
45using css::uno::UNO_QUERY;
46using css::uno::UNO_QUERY_THROW;
48using css::uno::Sequence;
49using css::awt::grid::XGridSelectionListener;
50using css::style::VerticalAlignment;
51using css::style::VerticalAlignment_TOP;
52using css::view::SelectionType;
53using css::view::SelectionType_NONE;
54using css::view::SelectionType_RANGE;
55using css::view::SelectionType_SINGLE;
56using css::view::SelectionType_MULTI;
57using css::awt::grid::XGridDataModel;
58using css::awt::grid::GridInvalidDataException;
59using css::lang::EventObject;
60using css::lang::IndexOutOfBoundsException;
61using css::awt::grid::XGridColumnModel;
62using css::awt::grid::GridSelectionEvent;
63using css::awt::grid::XGridColumn;
64using css::container::ContainerEvent;
65using css::awt::grid::GridDataEvent;
66using css::awt::grid::GridInvalidModelException;
68namespace AccessibleEventId = css::accessibility::AccessibleEventId;
69namespace AccessibleStateType = css::accessibility::AccessibleStateType;
76 ,m_bTableModelInitCompleted( false )
77 ,m_aSelectionListeners( *this )
89 SVTXGridControl_Base::SetWindow( pWindow );
96 if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.
GetColumnCount() ) )
97 throw IndexOutOfBoundsException( OUString(), *
const_cast< SVTXGridControl*
>(
this ) );
103 if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.
GetRowCount() ) )
104 throw IndexOutOfBoundsException( OUString(), *
const_cast< SVTXGridControl*
>(
this ) );
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;
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;
137 ENSURE_OR_RETURN( pTable,
"SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 );
139 sal_Int32
const nColumn = pTable->GetCurrentColumn();
140 return ( nColumn >= 0 ) ? nColumn : -1;
149 ENSURE_OR_RETURN( pTable,
"SVTXGridControl::getCurrentRow: no control (anymore)!", -1 );
151 sal_Int32
const nRow = pTable->GetCurrentRow();
152 return ( nRow >= 0 ) ? nRow : -1;
166 pTable->GoTo( i_columnIndex, i_rowIndex );
193 sal_Int32 rowHeaderWidth( -1 );
194 aValue >>= rowHeaderWidth;
195 if ( rowHeaderWidth <= 0 )
197 SAL_WARN(
"svtools.uno",
"SVTXGridControl::setProperty: illegal row header width!" );
203 pTable->Invalidate();
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!" );
226 pTable->Invalidate();
232 GridTableRenderer* pGridRenderer =
dynamic_cast< GridTableRenderer*
>(
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();
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;
259 if ( rowHeight <= 0 )
261 SAL_WARN(
"svtools.uno",
"SVTXGridControl::setProperty: illegal row height!" );
266 pTable->Invalidate();
275 if ( pTable->IsBackground() )
276 pTable->getDataWindow().SetBackground( pTable->GetBackground() );
278 pTable->getDataWindow().SetBackground();
285 if( aValue >>= eSelectionType )
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 );
302 bool bHScroll =
true;
303 if( aValue >>= bHScroll )
310 bool bVScroll =
true;
311 if( aValue >>= bVScroll )
320 bool rowHeader =
true;
321 if( aValue >>= rowHeader )
330 pTable->Invalidate();
335 pTable->Invalidate();
340 pTable->Invalidate();
345 pTable->Invalidate();
350 pTable->Invalidate();
355 pTable->Invalidate();
360 pTable->Invalidate();
365 pTable->Invalidate();
371 pTable->Invalidate();
376 pTable->Invalidate();
381 VerticalAlignment eAlign( VerticalAlignment_TOP );
382 if ( aValue >>= eAlign )
389 bool colHeader =
true;
390 if( aValue >>= colHeader )
398 Reference< XGridDataModel >
const xDataModel( aValue, UNO_QUERY );
399 if ( !xDataModel.is() )
400 throw GridInvalidDataException(
"Invalid data model.", *
this );
410 Reference< XGridColumnModel >
const xColumnModel( aValue, UNO_QUERY );
411 if ( !xColumnModel.is() )
412 throw GridInvalidModelException(
"Invalid column model.", *
this );
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 );
457 void lcl_convertColor( ::std::optional< ::Color >
const & i_color, Any & o_colorValue )
460 o_colorValue.clear();
462 o_colorValue <<= sal_Int32(*i_color);
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;
513 aPropertyValue <<= bHasScrollbar;
520 aPropertyValue <<= bHasScrollbar;
526 GridTableRenderer* pGridRenderer =
dynamic_cast< GridTableRenderer*
>(
528 if ( !pGridRenderer )
530 SAL_WARN(
"svtools.uno",
"SVTXGridControl::getProperty(UseGridLines): invalid renderer!" );
534 aPropertyValue <<= pGridRenderer->useGridLines();
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;
554 lcl_convertColor(
m_xTableModel->getLineColor(), aPropertyValue );
558 lcl_convertColor(
m_xTableModel->getHeaderBackgroundColor(), aPropertyValue );
562 lcl_convertColor(
m_xTableModel->getHeaderTextColor(), aPropertyValue );
566 lcl_convertColor(
m_xTableModel->getActiveSelectionBackColor(), aPropertyValue );
570 lcl_convertColor(
m_xTableModel->getInactiveSelectionBackColor(), aPropertyValue );
574 lcl_convertColor(
m_xTableModel->getActiveSelectionTextColor(), aPropertyValue );
578 lcl_convertColor(
m_xTableModel->getInactiveSelectionTextColor(), aPropertyValue );
582 lcl_convertColor(
m_xTableModel->getTextColor(), aPropertyValue );
586 lcl_convertColor(
m_xTableModel->getTextLineColor(), aPropertyValue );
594 return aPropertyValue;
623 pTable->getTableControlInterface().invalidate( TableArea::ColumnHeaders );
635 pTable->getTableControlInterface().invalidate( TableArea::RowHeaders );
643 Reference< XGridColumn >
const xGridColumn( i_event.Element, UNO_QUERY_THROW );
646 OSL_VERIFY( i_event.Accessor >>=
nIndex );
656 OSL_VERIFY( i_event.Accessor >>=
nIndex );
663 OSL_ENSURE(
false,
"SVTXGridControl::elementReplaced: not implemented!" );
684 pTable->SelectRow( i_rowIndex,
true );
695 pTable->SelectAllRows(
true );
708 pTable->SelectRow( i_rowIndex,
false );
719 pTable->SelectAllRows(
false );
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);
744 ENSURE_OR_RETURN( pTable,
"SVTXGridControl::hasSelectedRows: no control (anymore)!",
true );
746 return pTable->GetSelectedRowCount() > 0;
755 ENSURE_OR_RETURN( pTable,
"SVTXGridControl::isRowSelected: no control (anymore)!",
false );
757 return pTable->IsRowSelected(
index );
774 Reference< XWindow > xKeepAlive(
this );
779 bool handled =
false;
780 switch ( rVclWindowEvent.
GetId() )
782 case VclEventId::TableRowSelect:
790 case VclEventId::ControlGetFocus:
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:
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 )
857 pWindow->Enable( bEnable );
858 pWindow->EnableInput( bEnable );
859 pWindow->Invalidate();
871 GridSelectionEvent
aEvent;
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 );
886 Reference< XGridColumnModel >
const xColumnModel(
m_xTableModel->getColumnModel() );
893 const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns();
894 for (
auto const & colRef : columns )
898 SAL_WARN(
"svtools.uno",
"illegal column!" );
void impl_checkColumnIndex_throw(::svt::table::TableControl const &i_table, sal_Int32 const i_columnIndex) const
virtual ::sal_Int32 SAL_CALL getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) override
virtual ::sal_Int32 SAL_CALL getCurrentRow() override
virtual void SAL_CALL rowsInserted(const css::awt::grid::GridDataEvent &Event) override
void ImplCallItemListeners()
virtual void SAL_CALL goToCell(::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex) override
virtual void SAL_CALL addSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > &listener) override
virtual void SAL_CALL rowHeadingChanged(const css::awt::grid::GridDataEvent &Event) override
void SAL_CALL setProperty(const OUString &PropertyName, const css::uno::Any &Value) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual sal_Bool SAL_CALL isRowSelected(::sal_Int32 index) override
virtual sal_Bool SAL_CALL hasSelectedRows() override
virtual void SetWindow(const VclPtr< vcl::Window > &pWindow) override
virtual void SAL_CALL selectRow(::sal_Int32 i_rowIndex) override
virtual void SAL_CALL removeSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > &listener) override
virtual void SAL_CALL elementReplaced(const css::container::ContainerEvent &Event) override
bool m_bTableModelInitCompleted
void impl_checkRowIndex_throw(::svt::table::TableControl const &i_table, sal_Int32 const i_rowIndex) const
virtual void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent) override
virtual void SAL_CALL elementInserted(const css::container::ContainerEvent &Event) override
virtual void SAL_CALL selectAllRows() override
virtual css::uno::Sequence< ::sal_Int32 > SAL_CALL getSelectedRows() override
virtual void SAL_CALL elementRemoved(const css::container::ContainerEvent &Event) override
SelectionListenerMultiplexer m_aSelectionListeners
virtual ::sal_Int32 SAL_CALL getCurrentColumn() override
std::shared_ptr< ::svt::table::UnoControlTableModel > m_xTableModel
void SAL_CALL dispose() override
virtual ~SVTXGridControl() override
void impl_updateColumnsFromModel_nothrow()
virtual void SAL_CALL dataChanged(const css::awt::grid::GridDataEvent &Event) override
virtual void SAL_CALL deselectAllRows() override
virtual ::sal_Int32 SAL_CALL getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) override
css::uno::Any SAL_CALL getProperty(const OUString &PropertyName) override
void SAL_CALL setEnable(sal_Bool bEnable) override
virtual void SAL_CALL deselectRow(::sal_Int32 i_rowIndex) override
void impl_checkTableModelInit()
virtual void SAL_CALL rowsRemoved(const css::awt::grid::GridDataEvent &Event) override
virtual void ProcessWindowEvent(const VclWindowEvent &rVclWindowEvent)
css::uno::Any SAL_CALL getProperty(const OUString &PropertyName) override
void SAL_CALL setProperty(const OUString &PropertyName, const css::uno::Any &Value) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
void SAL_CALL dispose() override
a basic control which manages table-like data, i.e.
virtual sal_Int32 GetColumnCount() const override
virtual sal_Int32 GetRowCount() const override
#define ENSURE_OR_RETURN(c, m, r)
#define DBG_UNHANDLED_EXCEPTION(...)
#define ENSURE_OR_RETURN_VOID(c, m)
#define SAL_WARN(area, stream)
std::shared_ptr< T > make_shared(Args &&... args)
std::shared_ptr< ITableModel > PTableModel
@ ScrollbarShowNever
enumeration value denoting that a scrollbar should never be visible, even if needed normally
@ ScrollbarShowSmart
enumeration value denoting that a scrollbar should be visible when needed only
@ ScrollbarShowAlways
enumeration value denoting that a scrollbar should always be visible, even if not needed normally
sal_uInt16 GetPropertyId(const OUString &rPropertyName)
#define BASEPROPERTY_USE_GRID_LINES
#define BASEPROPERTY_GRID_COLUMNMODEL
#define BASEPROPERTY_TEXTLINECOLOR
#define BASEPROPERTY_GRID_SHOWROWHEADER
#define BASEPROPERTY_GRID_DATAMODEL
#define BASEPROPERTY_HSCROLL
#define BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
#define BASEPROPERTY_GRID_LINE_COLOR
#define BASEPROPERTY_GRID_HEADER_TEXT_COLOR
#define BASEPROPERTY_ROW_HEADER_WIDTH
#define BASEPROPERTY_GRID_SHOWCOLUMNHEADER
#define BASEPROPERTY_BACKGROUNDCOLOR
#define BASEPROPERTY_GRID_HEADER_BACKGROUND
#define BASEPROPERTY_VERTICALALIGN
#define BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
#define BASEPROPERTY_VSCROLL
#define BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
#define BASEPROPERTY_COLUMN_HEADER_HEIGHT
#define BASEPROPERTY_ROW_HEIGHT
#define BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
#define BASEPROPERTY_GRID_SELECTIONMODE
#define BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
#define BASEPROPERTY_TEXTCOLOR