LibreOffice Module toolkit (master) 1
svtxgridcontrol.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <awt/vclxwindows.hxx>
23#include <com/sun/star/view/SelectionType.hpp>
28#include <sal/log.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>
38
39#include <vcl/svapp.hxx>
40
41#include <algorithm>
42
43using css::uno::Reference;
44using css::uno::Exception;
45using css::uno::UNO_QUERY;
46using css::uno::UNO_QUERY_THROW;
47using css::uno::Any;
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;
67
68namespace AccessibleEventId = css::accessibility::AccessibleEventId;
69namespace AccessibleStateType = css::accessibility::AccessibleStateType;
70
71using namespace ::svt::table;
72
73
75 :m_xTableModel( std::make_shared<UnoControlTableModel>() )
76 ,m_bTableModelInitCompleted( false )
77 ,m_aSelectionListeners( *this )
78{
79}
80
81
83{
84}
85
86
88{
89 SVTXGridControl_Base::SetWindow( pWindow );
91}
92
93
94void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const
95{
96 if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) )
97 throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl* >( this ) );
98}
99
100
101void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const
102{
103 if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) )
104 throw IndexOutOfBoundsException( OUString(), *const_cast< SVTXGridControl* >( this ) );
105}
106
107
108sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y)
109{
110 SolarMutexGuard aGuard;
111
112 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
113 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 );
114
115 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) );
116 return ( tableCell.nRow >= 0 ) ? tableCell.nRow : -1;
117}
118
119
120sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y)
121{
122 SolarMutexGuard aGuard;
123
124 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
125 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 );
126
127 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) );
128 return ( tableCell.nColumn >= 0 ) ? tableCell.nColumn : -1;
129}
130
131
133{
134 SolarMutexGuard aGuard;
135
136 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
137 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 );
138
139 sal_Int32 const nColumn = pTable->GetCurrentColumn();
140 return ( nColumn >= 0 ) ? nColumn : -1;
141}
142
143
145{
146 SolarMutexGuard aGuard;
147
148 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
149 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 );
150
151 sal_Int32 const nRow = pTable->GetCurrentRow();
152 return ( nRow >= 0 ) ? nRow : -1;
153}
154
155
156void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex )
157{
158 SolarMutexGuard aGuard;
159
160 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
161 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::getCurrentRow: no control (anymore)!" );
162
163 impl_checkColumnIndex_throw( *pTable, i_columnIndex );
164 impl_checkRowIndex_throw( *pTable, i_rowIndex );
165
166 pTable->GoTo( i_columnIndex, i_rowIndex );
167}
168
169
170void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener)
171{
172 m_aSelectionListeners.addInterface(listener);
173}
174
175
176void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener)
177{
178 m_aSelectionListeners.removeInterface(listener);
179}
180
181
182void SVTXGridControl::setProperty( const OUString& PropertyName, const Any& aValue)
183{
184 SolarMutexGuard aGuard;
185
186 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
187 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::setProperty: no control (anymore)!" );
188
189 switch( GetPropertyId( PropertyName ) )
190 {
192 {
193 sal_Int32 rowHeaderWidth( -1 );
194 aValue >>= rowHeaderWidth;
195 if ( rowHeaderWidth <= 0 )
196 {
197 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row header width!" );
198 break;
199 }
200
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();
204 }
205 break;
206
208 {
209 sal_Int32 columnHeaderHeight = 0;
210 if ( !aValue.hasValue() )
211 {
212 columnHeaderHeight = pTable->PixelToLogic(Size(0, pTable->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont)).Height();
213 }
214 else
215 {
216 aValue >>= columnHeaderHeight;
217 }
218 if ( columnHeaderHeight <= 0 )
219 {
220 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal column header width!" );
221 break;
222 }
223
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();
227 }
228 break;
229
231 {
232 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >(
233 m_xTableModel->getRenderer().get() );
234 if ( !pGridRenderer )
235 {
236 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" );
237 break;
238 }
239
240 bool bUseGridLines = false;
241 OSL_VERIFY( aValue >>= bUseGridLines );
242 pGridRenderer->useGridLines( bUseGridLines );
243 pTable->Invalidate();
244 }
245 break;
246
248 {
249 sal_Int32 rowHeight = 0;
250 if ( !aValue.hasValue() )
251 {
252 rowHeight = pTable->PixelToLogic(Size(0, pTable->GetTextHeight() + 3), MapMode(MapUnit::MapAppFont)).Height();
253 }
254 else
255 {
256 aValue >>= rowHeight;
257 }
258 m_xTableModel->setRowHeight( rowHeight );
259 if ( rowHeight <= 0 )
260 {
261 SAL_WARN( "svtools.uno", "SVTXGridControl::setProperty: illegal row height!" );
262 break;
263 }
264
265 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
266 pTable->Invalidate();
267 }
268 break;
269
271 {
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() );
277 else
278 pTable->getDataWindow().SetBackground();
279 }
280 break;
281
283 {
284 SelectionType eSelectionType;
285 if( aValue >>= eSelectionType )
286 {
287 SelectionMode eSelMode;
288 switch( eSelectionType )
289 {
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;
294 }
295 if( pTable->getSelEngine()->GetSelectionMode() != eSelMode )
296 pTable->getSelEngine()->SetSelectionMode( eSelMode );
297 }
298 break;
299 }
301 {
302 bool bHScroll = true;
303 if( aValue >>= bHScroll )
304 m_xTableModel->setHorizontalScrollbarVisibility( bHScroll ? ScrollbarShowAlways : ScrollbarShowSmart );
305 break;
306 }
307
309 {
310 bool bVScroll = true;
311 if( aValue >>= bVScroll )
312 {
313 m_xTableModel->setVerticalScrollbarVisibility( bVScroll ? ScrollbarShowAlways : ScrollbarShowSmart );
314 }
315 break;
316 }
317
319 {
320 bool rowHeader = true;
321 if( aValue >>= rowHeader )
322 {
323 m_xTableModel->setRowHeaders(rowHeader);
324 }
325 break;
326 }
327
329 m_xTableModel->setRowBackgroundColors( aValue );
330 pTable->Invalidate();
331 break;
332
334 m_xTableModel->setLineColor( aValue );
335 pTable->Invalidate();
336 break;
337
339 m_xTableModel->setHeaderBackgroundColor( aValue );
340 pTable->Invalidate();
341 break;
342
344 m_xTableModel->setHeaderTextColor( aValue );
345 pTable->Invalidate();
346 break;
347
349 m_xTableModel->setActiveSelectionBackColor( aValue );
350 pTable->Invalidate();
351 break;
352
354 m_xTableModel->setInactiveSelectionBackColor( aValue );
355 pTable->Invalidate();
356 break;
357
359 m_xTableModel->setActiveSelectionTextColor( aValue );
360 pTable->Invalidate();
361 break;
362
364 m_xTableModel->setInactiveSelectionTextColor( aValue );
365 pTable->Invalidate();
366 break;
367
368
370 m_xTableModel->setTextColor( aValue );
371 pTable->Invalidate();
372 break;
373
375 m_xTableModel->setTextLineColor( aValue );
376 pTable->Invalidate();
377 break;
378
380 {
381 VerticalAlignment eAlign( VerticalAlignment_TOP );
382 if ( aValue >>= eAlign )
383 m_xTableModel->setVerticalAlign( eAlign );
384 break;
385 }
386
388 {
389 bool colHeader = true;
390 if( aValue >>= colHeader )
391 {
392 m_xTableModel->setColumnHeaders(colHeader);
393 }
394 break;
395 }
397 {
398 Reference< XGridDataModel > const xDataModel( aValue, UNO_QUERY );
399 if ( !xDataModel.is() )
400 throw GridInvalidDataException("Invalid data model.", *this );
401
402 m_xTableModel->setDataModel( xDataModel );
404 }
405 break;
406
408 {
409 // obtain new col model
410 Reference< XGridColumnModel > const xColumnModel( aValue, UNO_QUERY );
411 if ( !xColumnModel.is() )
412 throw GridInvalidModelException("Invalid column model.", *this );
413
414 // remove all old columns
415 m_xTableModel->removeAllColumns();
416
417 // announce to the TableModel
418 m_xTableModel->setColumnModel( xColumnModel );
420
421 // add new columns
423 break;
424 }
425 default:
426 VCLXWindow::setProperty( PropertyName, aValue );
427 break;
428 }
429}
430
431
433{
434 if ( !(!m_bTableModelInitCompleted && m_xTableModel->hasColumnModel() && m_xTableModel->hasDataModel()) )
435 return;
436
437 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
438 if ( !pTable )
439 return;
440
441 pTable->SetModel( PTableModel( m_xTableModel ) );
442
444
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 );
448
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
453}
454
455namespace
456{
457 void lcl_convertColor( ::std::optional< ::Color > const & i_color, Any & o_colorValue )
458 {
459 if ( !i_color )
460 o_colorValue.clear();
461 else
462 o_colorValue <<= sal_Int32(*i_color);
463 }
464}
465
466Any SVTXGridControl::getProperty( const OUString& PropertyName )
467{
468 SolarMutexGuard aGuard;
469
470 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
471 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getProperty: no control (anymore)!", Any() );
472
473 Any aPropertyValue;
474
475 const sal_uInt16 nPropId = GetPropertyId( PropertyName );
476 switch(nPropId)
477 {
479 {
480 SelectionType eSelectionType;
481
482 SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
483 switch( eSelMode )
484 {
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;
489 }
490 aPropertyValue <<= eSelectionType;
491 break;
492 }
493
495 aPropertyValue <<= m_xTableModel->hasRowHeaders();
496 break;
497
499 aPropertyValue <<= m_xTableModel->hasColumnHeaders();
500 break;
501
503 aPropertyValue <<= m_xTableModel->getDataModel();
504 break;
505
507 aPropertyValue <<= m_xTableModel->getColumnModel();
508 break;
509
511 {
512 bool const bHasScrollbar = ( m_xTableModel->getHorizontalScrollbarVisibility() != ScrollbarShowNever );
513 aPropertyValue <<= bHasScrollbar;
514 break;
515 }
516
518 {
519 bool const bHasScrollbar = ( m_xTableModel->getVerticalScrollbarVisibility() != ScrollbarShowNever );
520 aPropertyValue <<= bHasScrollbar;
521 break;
522 }
523
525 {
526 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >(
527 m_xTableModel->getRenderer().get() );
528 if ( !pGridRenderer )
529 {
530 SAL_WARN( "svtools.uno", "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" );
531 break;
532 }
533
534 aPropertyValue <<= pGridRenderer->useGridLines();
535 }
536 break;
537
539 {
540 ::std::optional< ::std::vector< ::Color > > aColors( m_xTableModel->getRowBackgroundColors() );
541 if ( !aColors )
542 aPropertyValue.clear();
543 else
544 {
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;
549 }
550 }
551 break;
552
554 lcl_convertColor( m_xTableModel->getLineColor(), aPropertyValue );
555 break;
556
558 lcl_convertColor( m_xTableModel->getHeaderBackgroundColor(), aPropertyValue );
559 break;
560
562 lcl_convertColor( m_xTableModel->getHeaderTextColor(), aPropertyValue );
563 break;
564
566 lcl_convertColor( m_xTableModel->getActiveSelectionBackColor(), aPropertyValue );
567 break;
568
570 lcl_convertColor( m_xTableModel->getInactiveSelectionBackColor(), aPropertyValue );
571 break;
572
574 lcl_convertColor( m_xTableModel->getActiveSelectionTextColor(), aPropertyValue );
575 break;
576
578 lcl_convertColor( m_xTableModel->getInactiveSelectionTextColor(), aPropertyValue );
579 break;
580
582 lcl_convertColor( m_xTableModel->getTextColor(), aPropertyValue );
583 break;
584
586 lcl_convertColor( m_xTableModel->getTextLineColor(), aPropertyValue );
587 break;
588
589 default:
590 aPropertyValue = VCLXWindow::getProperty( PropertyName );
591 break;
592 }
593
594 return aPropertyValue;
595}
596
597
598void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event )
599{
600 SolarMutexGuard aGuard;
601 m_xTableModel->notifyRowsInserted( i_event );
602}
603
604
605void SAL_CALL
606 SVTXGridControl::rowsRemoved( const GridDataEvent& i_event )
607{
608 SolarMutexGuard aGuard;
609 m_xTableModel->notifyRowsRemoved( i_event );
610}
611
612
613void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event )
614{
615 SolarMutexGuard aGuard;
616
617 m_xTableModel->notifyDataChanged( i_event );
618
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 );
624}
625
626
627void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& )
628{
629 SolarMutexGuard aGuard;
630
631 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
632 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" );
633
634 // TODO: we could do better than this - invalidate the header area only
635 pTable->getTableControlInterface().invalidate( TableArea::RowHeaders );
636}
637
638
639void SAL_CALL SVTXGridControl::elementInserted( const ContainerEvent& i_event )
640{
641 SolarMutexGuard aGuard;
642
643 Reference< XGridColumn > const xGridColumn( i_event.Element, UNO_QUERY_THROW );
644
645 sal_Int32 nIndex( m_xTableModel->getColumnCount() );
646 OSL_VERIFY( i_event.Accessor >>= nIndex );
647 m_xTableModel->insertColumn( nIndex, xGridColumn );
648}
649
650
651void SAL_CALL SVTXGridControl::elementRemoved( const ContainerEvent& i_event )
652{
653 SolarMutexGuard aGuard;
654
655 sal_Int32 nIndex( -1 );
656 OSL_VERIFY( i_event.Accessor >>= nIndex );
657 m_xTableModel->removeColumn( nIndex );
658}
659
660
661void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& )
662{
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
666}
667
668
669void SAL_CALL SVTXGridControl::disposing( const EventObject& Source )
670{
672}
673
674
675void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex )
676{
677 SolarMutexGuard aGuard;
678
679 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
680 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" );
681
682 impl_checkRowIndex_throw( *pTable, i_rowIndex );
683
684 pTable->SelectRow( i_rowIndex, true );
685}
686
687
689{
690 SolarMutexGuard aGuard;
691
692 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
693 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectAllRows: no control (anymore)!" );
694
695 pTable->SelectAllRows( true );
696}
697
698
699void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex )
700{
701 SolarMutexGuard aGuard;
702
703 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
704 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" );
705
706 impl_checkRowIndex_throw( *pTable, i_rowIndex );
707
708 pTable->SelectRow( i_rowIndex, false );
709}
710
711
713{
714 SolarMutexGuard aGuard;
715
716 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
717 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectAllRows: no control (anymore)!" );
718
719 pTable->SelectAllRows( false );
720}
721
722
723Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows()
724{
725 SolarMutexGuard aGuard;
726
727 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
728 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() );
729
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);
735 return selectedRows;
736}
737
738
740{
741 SolarMutexGuard aGuard;
742
743 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
744 ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", true );
745
746 return pTable->GetSelectedRowCount() > 0;
747}
748
749
750sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index )
751{
752 SolarMutexGuard aGuard;
753
754 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
755 ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", false );
756
757 return pTable->IsRowSelected( index );
758}
759
760
762{
763 EventObject aObj;
764 aObj.Source = static_cast<cppu::OWeakObject*>(this);
765 m_aSelectionListeners.disposeAndClear( aObj );
767}
768
769
771{
772 SolarMutexGuard aGuard;
773
774 Reference< XWindow > xKeepAlive( this );
775
776 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
777 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" );
778
779 bool handled = false;
780 switch ( rVclWindowEvent.GetId() )
781 {
782 case VclEventId::TableRowSelect:
783 {
784 if ( m_aSelectionListeners.getLength() )
786 handled = true;
787 }
788 break;
789
790 case VclEventId::ControlGetFocus:
791 {
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 )
795 {
796 pTable->commitCellEventIfAccessibleAlive(
797 AccessibleEventId::STATE_CHANGED,
798 Any( AccessibleStateType::FOCUSED ),
799 Any()
800 );
801 pTable->commitTableEventIfAccessibleAlive(
802 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
803 Any(),
804 Any()
805 );
806 }
807 else
808 {
809 pTable->commitTableEventIfAccessibleAlive(
810 AccessibleEventId::STATE_CHANGED,
811 Any( AccessibleStateType::FOCUSED ),
812 Any()
813 );
814 }
815 }
816 break;
817
818 case VclEventId::ControlLoseFocus:
819 {
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 )
823 {
824 pTable->commitCellEventIfAccessibleAlive(
825 AccessibleEventId::STATE_CHANGED,
826 Any(),
827 Any( AccessibleStateType::FOCUSED )
828 );
829 }
830 else
831 {
832 pTable->commitTableEventIfAccessibleAlive(
833 AccessibleEventId::STATE_CHANGED,
834 Any(),
835 Any( AccessibleStateType::FOCUSED )
836 );
837 }
838 }
839 break;
840
841 default: break;
842 }
843
844 if ( !handled )
845 VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
846}
847
848
850{
851 SolarMutexGuard aGuard;
852
853 m_xTableModel->setEnabled( bEnable );
854 VclPtr<vcl::Window> pWindow = GetWindow();
855 if ( pWindow )
856 {
857 pWindow->Enable( bEnable );
858 pWindow->EnableInput( bEnable );
859 pWindow->Invalidate();
860 }
861}
862
863
865{
866 VclPtr< TableControl > pTable = GetAsDynamic< TableControl >();
867 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" );
868
869 if ( m_aSelectionListeners.getLength() )
870 {
871 GridSelectionEvent aEvent;
872 aEvent.Source = static_cast<cppu::OWeakObject*>(this);
873
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 );
880 }
881}
882
883
885{
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!" );
890
891 try
892 {
893 const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns();
894 for ( auto const & colRef : columns )
895 {
896 if ( !colRef.is() )
897 {
898 SAL_WARN( "svtools.uno", "illegal column!" );
899 continue;
900 }
901
902 m_xTableModel->appendColumn( colRef );
903 }
904 }
905 catch( const Exception& )
906 {
907 DBG_UNHANDLED_EXCEPTION("svtools.uno");
908 }
909}
910
911/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
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
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
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)
Definition: vclxwindow.cxx:426
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
Definition: vclxwindow.cxx:907
VclEventId GetId() const
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)
float y
float x
sal_Int32 nIndex
#define SAL_WARN(area, stream)
@ Exception
int i
index
std::shared_ptr< T > make_shared(Args &&... args)
std::shared_ptr< ITableModel > PTableModel
Definition: tablemodel.hxx:448
@ ScrollbarShowNever
enumeration value denoting that a scrollbar should never be visible, even if needed normally
Definition: tablemodel.hxx:65
@ ScrollbarShowSmart
enumeration value denoting that a scrollbar should be visible when needed only
Definition: tablemodel.hxx:68
@ ScrollbarShowAlways
enumeration value denoting that a scrollbar should always be visible, even if not needed normally
Definition: tablemodel.hxx:72
sal_uInt16 GetPropertyId(const OUString &rPropertyName)
Definition: property.cxx:278
#define BASEPROPERTY_USE_GRID_LINES
Definition: property.hxx:196
#define BASEPROPERTY_GRID_COLUMNMODEL
Definition: property.hxx:178
#define BASEPROPERTY_TEXTLINECOLOR
Definition: property.hxx:118
#define BASEPROPERTY_GRID_SHOWROWHEADER
Definition: property.hxx:175
#define BASEPROPERTY_GRID_DATAMODEL
Definition: property.hxx:177
#define BASEPROPERTY_HSCROLL
Definition: property.hxx:45
#define BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
Definition: property.hxx:203
#define BASEPROPERTY_GRID_LINE_COLOR
Definition: property.hxx:187
#define BASEPROPERTY_GRID_HEADER_TEXT_COLOR
Definition: property.hxx:185
#define BASEPROPERTY_ROW_HEADER_WIDTH
Definition: property.hxx:194
#define BASEPROPERTY_GRID_SHOWCOLUMNHEADER
Definition: property.hxx:176
#define BASEPROPERTY_BACKGROUNDCOLOR
Definition: property.hxx:35
#define BASEPROPERTY_GRID_HEADER_BACKGROUND
Definition: property.hxx:184
#define BASEPROPERTY_VERTICALALIGN
Definition: property.hxx:148
#define BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
Definition: property.hxx:186
#define BASEPROPERTY_VSCROLL
Definition: property.hxx:46
#define BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
Definition: property.hxx:201
#define BASEPROPERTY_COLUMN_HEADER_HEIGHT
Definition: property.hxx:195
#define BASEPROPERTY_ROW_HEIGHT
Definition: property.hxx:164
#define BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
Definition: property.hxx:202
#define BASEPROPERTY_GRID_SELECTIONMODE
Definition: property.hxx:179
#define BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
Definition: property.hxx:204
#define BASEPROPERTY_TEXTCOLOR
Definition: property.hxx:37
unsigned char sal_Bool
SelectionMode
SelectionType