1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23 // MARKER(update_precomp.py): autogen include statement, do not remove
24 #include "precompiled_svtools.hxx"
25
26 #include "svtxgridcontrol.hxx"
27 #include <com/sun/star/view/SelectionType.hpp>
28 #include "svtools/table/tablecontrolinterface.hxx"
29 #include "svtools/table/gridtablerenderer.hxx"
30 #include "svtools/table/tablecontrol.hxx"
31 #include "unocontroltablemodel.hxx"
32 #include <comphelper/sequence.hxx>
33 #include <rtl/ref.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <toolkit/helper/property.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <comphelper/processfactory.hxx>
38 #include <com/sun/star/awt/grid/XGridColumn.hpp>
39 #include <com/sun/star/awt/XControl.hpp>
40 #include <com/sun/star/awt/grid/GridInvalidDataException.hpp>
41 #include <com/sun/star/awt/grid/GridInvalidModelException.hpp>
42 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
44 #include <com/sun/star/util/Color.hpp>
45 #include <com/sun/star/awt/FontDescriptor.hpp>
46
47 /** === begin UNO using === **/
48 using ::com::sun::star::uno::RuntimeException;
49 using ::com::sun::star::uno::Reference;
50 using ::com::sun::star::uno::Exception;
51 using ::com::sun::star::uno::UNO_QUERY;
52 using ::com::sun::star::uno::UNO_QUERY_THROW;
53 using ::com::sun::star::uno::Any;
54 using ::com::sun::star::uno::makeAny;
55 using ::com::sun::star::uno::Sequence;
56 using ::com::sun::star::awt::grid::XGridSelectionListener;
57 using ::com::sun::star::style::VerticalAlignment;
58 using ::com::sun::star::style::VerticalAlignment_TOP;
59 using ::com::sun::star::view::SelectionType;
60 using ::com::sun::star::view::SelectionType_NONE;
61 using ::com::sun::star::view::SelectionType_RANGE;
62 using ::com::sun::star::view::SelectionType_SINGLE;
63 using ::com::sun::star::view::SelectionType_MULTI;
64 using ::com::sun::star::awt::grid::XGridDataModel;
65 using ::com::sun::star::awt::grid::GridInvalidDataException;
66 using ::com::sun::star::lang::EventObject;
67 using ::com::sun::star::lang::IndexOutOfBoundsException;
68 using ::com::sun::star::awt::grid::XGridColumnModel;
69 using ::com::sun::star::awt::grid::GridSelectionEvent;
70 using ::com::sun::star::awt::grid::XGridColumn;
71 using ::com::sun::star::container::ContainerEvent;
72 using ::com::sun::star::awt::grid::GridDataEvent;
73 using ::com::sun::star::awt::grid::GridInvalidModelException;
74 using ::com::sun::star::util::VetoException;
75 /** === end UNO using === **/
76
77 namespace AccessibleEventId = ::com::sun::star::accessibility::AccessibleEventId;
78 namespace AccessibleStateType = ::com::sun::star::accessibility::AccessibleStateType;
79
80 using namespace ::svt::table;
81
82 typedef ::com::sun::star::util::Color UnoColor;
83
84 // ---------------------------------------------------------------------------------------------------------------------
SVTXGridControl()85 SVTXGridControl::SVTXGridControl()
86 :m_pTableModel( new UnoControlTableModel() )
87 ,m_bTableModelInitCompleted( false )
88 ,m_aSelectionListeners( *this )
89 {
90 }
91
92 // ---------------------------------------------------------------------------------------------------------------------
~SVTXGridControl()93 SVTXGridControl::~SVTXGridControl()
94 {
95 }
96
97 // ---------------------------------------------------------------------------------------------------------------------
SetWindow(Window * pWindow)98 void SVTXGridControl::SetWindow( Window* pWindow )
99 {
100 SVTXGridControl_Base::SetWindow( pWindow );
101 impl_checkTableModelInit();
102 }
103
104 // ---------------------------------------------------------------------------------------------------------------------
impl_checkColumnIndex_throw(::svt::table::TableControl const & i_table,sal_Int32 const i_columnIndex) const105 void SVTXGridControl::impl_checkColumnIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_columnIndex ) const
106 {
107 if ( ( i_columnIndex < 0 ) || ( i_columnIndex >= i_table.GetColumnCount() ) )
108 throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) );
109 }
110
111 // ---------------------------------------------------------------------------------------------------------------------
impl_checkRowIndex_throw(::svt::table::TableControl const & i_table,sal_Int32 const i_rowIndex) const112 void SVTXGridControl::impl_checkRowIndex_throw( ::svt::table::TableControl const & i_table, sal_Int32 const i_rowIndex ) const
113 {
114 if ( ( i_rowIndex < 0 ) || ( i_rowIndex >= i_table.GetRowCount() ) )
115 throw IndexOutOfBoundsException( ::rtl::OUString(), *const_cast< SVTXGridControl* >( this ) );
116 }
117
118 // ---------------------------------------------------------------------------------------------------------------------
getRowAtPoint(::sal_Int32 x,::sal_Int32 y)119 sal_Int32 SAL_CALL SVTXGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException)
120 {
121 ::vos::OGuard aGuard( GetMutex() );
122
123 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
124 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getRowAtPoint: no control (anymore)!", -1 );
125
126 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) );
127 return ( tableCell.nRow >= 0 ) ? tableCell.nRow : -1;
128 }
129
130 // ---------------------------------------------------------------------------------------------------------------------
getColumnAtPoint(::sal_Int32 x,::sal_Int32 y)131 sal_Int32 SAL_CALL SVTXGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (RuntimeException)
132 {
133 ::vos::OGuard aGuard( GetMutex() );
134
135 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
136 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getColumnAtPoint: no control (anymore)!", -1 );
137
138 TableCell const tableCell = pTable->getTableControlInterface().hitTest( Point( x, y ) );
139 return ( tableCell.nColumn >= 0 ) ? tableCell.nColumn : -1;
140 }
141
142 // ---------------------------------------------------------------------------------------------------------------------
getCurrentColumn()143 sal_Int32 SAL_CALL SVTXGridControl::getCurrentColumn( ) throw (RuntimeException)
144 {
145 ::vos::OGuard aGuard( GetMutex() );
146
147 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
148 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentColumn: no control (anymore)!", -1 );
149
150 sal_Int32 const nColumn = pTable->GetCurrentColumn();
151 return ( nColumn >= 0 ) ? nColumn : -1;
152 }
153
154 // ---------------------------------------------------------------------------------------------------------------------
getCurrentRow()155 sal_Int32 SAL_CALL SVTXGridControl::getCurrentRow( ) throw (RuntimeException)
156 {
157 ::vos::OGuard aGuard( GetMutex() );
158
159 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
160 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!", -1 );
161
162 sal_Int32 const nRow = pTable->GetCurrentRow();
163 return ( nRow >= 0 ) ? nRow : -1;
164 }
165
166 //----------------------------------------------------------------------------------------------------------------------
goToCell(::sal_Int32 i_columnIndex,::sal_Int32 i_rowIndex)167 void SAL_CALL SVTXGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException)
168 {
169 ::vos::OGuard aGuard( GetMutex() );
170
171 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
172 ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::getCurrentRow: no control (anymore)!" );
173
174 impl_checkColumnIndex_throw( *pTable, i_columnIndex );
175 impl_checkRowIndex_throw( *pTable, i_rowIndex );
176
177 pTable->GoTo( i_columnIndex, i_rowIndex );
178 }
179
180 // ---------------------------------------------------------------------------------------------------------------------
addSelectionListener(const Reference<XGridSelectionListener> & listener)181 void SAL_CALL SVTXGridControl::addSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException)
182 {
183 m_aSelectionListeners.addInterface(listener);
184 }
185
186 // ---------------------------------------------------------------------------------------------------------------------
removeSelectionListener(const Reference<XGridSelectionListener> & listener)187 void SAL_CALL SVTXGridControl::removeSelectionListener(const Reference< XGridSelectionListener > & listener) throw (RuntimeException)
188 {
189 m_aSelectionListeners.removeInterface(listener);
190 }
191
192 // ---------------------------------------------------------------------------------------------------------------------
setProperty(const::rtl::OUString & PropertyName,const Any & aValue)193 void SVTXGridControl::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException)
194 {
195 ::vos::OGuard aGuard( GetMutex() );
196
197 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
198 ENSURE_OR_RETURN_VOID( pTable != NULL, "SVTXGridControl::setProperty: no control (anymore)!" );
199
200 switch( GetPropertyId( PropertyName ) )
201 {
202 case BASEPROPERTY_ROW_HEADER_WIDTH:
203 {
204 sal_Int32 rowHeaderWidth( -1 );
205 aValue >>= rowHeaderWidth;
206 ENSURE_OR_BREAK( rowHeaderWidth > 0, "SVTXGridControl::setProperty: illegal row header width!" );
207 m_pTableModel->setRowHeaderWidth( rowHeaderWidth );
208 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
209 pTable->Invalidate();
210 }
211 break;
212
213 case BASEPROPERTY_COLUMN_HEADER_HEIGHT:
214 {
215 sal_Int32 columnHeaderHeight = 0;
216 if ( !aValue.hasValue() )
217 {
218 columnHeaderHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height();
219 }
220 else
221 {
222 aValue >>= columnHeaderHeight;
223 }
224 ENSURE_OR_BREAK( columnHeaderHeight > 0, "SVTXGridControl::setProperty: illegal column header height!" );
225 m_pTableModel->setColumnHeaderHeight( columnHeaderHeight );
226 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
227 pTable->Invalidate();
228 }
229 break;
230
231 case BASEPROPERTY_USE_GRID_LINES:
232 {
233 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >(
234 m_pTableModel->getRenderer().get() );
235 ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::setProperty(UseGridLines): invalid renderer!" );
236 sal_Bool bUseGridLines = sal_False;
237 OSL_VERIFY( aValue >>= bUseGridLines );
238 pGridRenderer->useGridLines( bUseGridLines );
239 pTable->Invalidate();
240 }
241 break;
242
243 case BASEPROPERTY_ROW_HEIGHT:
244 {
245 sal_Int32 rowHeight = 0;
246 if ( !aValue.hasValue() )
247 {
248 rowHeight = pTable->PixelToLogic( Size( 0, pTable->GetTextHeight() + 3 ), MAP_APPFONT ).Height();
249 }
250 else
251 {
252 aValue >>= rowHeight;
253 }
254 m_pTableModel->setRowHeight( rowHeight );
255 ENSURE_OR_BREAK( rowHeight > 0, "SVTXGridControl::setProperty: illegal row height!" );
256 // TODO: the model should broadcast this change itself, and the table should invalidate itself as needed
257 pTable->Invalidate();
258 }
259 break;
260
261 case BASEPROPERTY_BACKGROUNDCOLOR:
262 {
263 // let the base class handle this for the TableControl
264 VCLXWindow::setProperty( PropertyName, aValue );
265 // and forward to the grid control's data window
266 if ( pTable->IsBackground() )
267 pTable->getDataWindow().SetBackground( pTable->GetBackground() );
268 else
269 pTable->getDataWindow().SetBackground();
270 }
271 break;
272
273 case BASEPROPERTY_GRID_SELECTIONMODE:
274 {
275 SelectionType eSelectionType;
276 if( aValue >>= eSelectionType )
277 {
278 SelectionMode eSelMode;
279 switch( eSelectionType )
280 {
281 case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break;
282 case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break;
283 case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break;
284 default: eSelMode = NO_SELECTION; break;
285 }
286 if( pTable->getSelEngine()->GetSelectionMode() != eSelMode )
287 pTable->getSelEngine()->SetSelectionMode( eSelMode );
288 }
289 break;
290 }
291 case BASEPROPERTY_HSCROLL:
292 {
293 sal_Bool bHScroll = true;
294 if( aValue >>= bHScroll )
295 m_pTableModel->setHorizontalScrollbarVisibility( bHScroll ? ScrollbarShowAlways : ScrollbarShowSmart );
296 break;
297 }
298
299 case BASEPROPERTY_VSCROLL:
300 {
301 sal_Bool bVScroll = true;
302 if( aValue >>= bVScroll )
303 {
304 m_pTableModel->setVerticalScrollbarVisibility( bVScroll ? ScrollbarShowAlways : ScrollbarShowSmart );
305 }
306 break;
307 }
308
309 case BASEPROPERTY_GRID_SHOWROWHEADER:
310 {
311 sal_Bool rowHeader = true;
312 if( aValue >>= rowHeader )
313 {
314 m_pTableModel->setRowHeaders(rowHeader);
315 }
316 break;
317 }
318
319 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS:
320 m_pTableModel->setRowBackgroundColors( aValue );
321 pTable->Invalidate();
322 break;
323
324 case BASEPROPERTY_GRID_LINE_COLOR:
325 m_pTableModel->setLineColor( aValue );
326 pTable->Invalidate();
327 break;
328
329 case BASEPROPERTY_GRID_HEADER_BACKGROUND:
330 m_pTableModel->setHeaderBackgroundColor( aValue );
331 pTable->Invalidate();
332 break;
333
334 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR:
335 m_pTableModel->setHeaderTextColor( aValue );
336 pTable->Invalidate();
337 break;
338
339 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
340 m_pTableModel->setActiveSelectionBackColor( aValue );
341 pTable->Invalidate();
342 break;
343
344 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
345 m_pTableModel->setInactiveSelectionBackColor( aValue );
346 pTable->Invalidate();
347 break;
348
349 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
350 m_pTableModel->setActiveSelectionTextColor( aValue );
351 pTable->Invalidate();
352 break;
353
354 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
355 m_pTableModel->setInactiveSelectionTextColor( aValue );
356 pTable->Invalidate();
357 break;
358
359
360 case BASEPROPERTY_TEXTCOLOR:
361 m_pTableModel->setTextColor( aValue );
362 pTable->Invalidate();
363 break;
364
365 case BASEPROPERTY_TEXTLINECOLOR:
366 m_pTableModel->setTextLineColor( aValue );
367 pTable->Invalidate();
368 break;
369
370 case BASEPROPERTY_VERTICALALIGN:
371 {
372 VerticalAlignment eAlign( VerticalAlignment_TOP );
373 if ( aValue >>= eAlign )
374 m_pTableModel->setVerticalAlign( eAlign );
375 break;
376 }
377
378 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
379 {
380 sal_Bool colHeader = true;
381 if( aValue >>= colHeader )
382 {
383 m_pTableModel->setColumnHeaders(colHeader);
384 }
385 break;
386 }
387 case BASEPROPERTY_GRID_DATAMODEL:
388 {
389 Reference< XGridDataModel > const xDataModel( aValue, UNO_QUERY );
390 if ( !xDataModel.is() )
391 throw GridInvalidDataException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid data model." ) ), *this );
392
393 m_pTableModel->setDataModel( xDataModel );
394 impl_checkTableModelInit();
395 }
396 break;
397
398 case BASEPROPERTY_GRID_COLUMNMODEL:
399 {
400 // obtain new col model
401 Reference< XGridColumnModel > const xColumnModel( aValue, UNO_QUERY );
402 if ( !xColumnModel.is() )
403 throw GridInvalidModelException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Invalid column model." ) ), *this );
404
405 // remove all old columns
406 m_pTableModel->removeAllColumns();
407
408 // announce to the TableModel
409 m_pTableModel->setColumnModel( xColumnModel );
410 impl_checkTableModelInit();
411
412 // add new columns
413 impl_updateColumnsFromModel_nothrow();
414 break;
415 }
416 default:
417 VCLXWindow::setProperty( PropertyName, aValue );
418 break;
419 }
420 }
421
422
impl_checkTableModelInit()423 void SVTXGridControl::impl_checkTableModelInit()
424 {
425 if ( !m_bTableModelInitCompleted && m_pTableModel->hasColumnModel() && m_pTableModel->hasDataModel() )
426 {
427 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
428 if ( pTable )
429 {
430 pTable->SetModel( PTableModel( m_pTableModel ) );
431
432 m_bTableModelInitCompleted = true;
433
434 // ensure default columns exist, if they have not previously been added
435 Reference< XGridDataModel > const xDataModel( m_pTableModel->getDataModel(), UNO_QUERY_THROW );
436 Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel(), UNO_QUERY_THROW );
437
438 sal_Int32 const nDataColumnCount = xDataModel->getColumnCount();
439 if ( ( nDataColumnCount > 0 ) && ( xColumnModel->getColumnCount() == 0 ) )
440 xColumnModel->setDefaultColumns( nDataColumnCount );
441 // this will trigger notifications, which in turn will let us update our m_pTableModel
442 }
443 }
444 }
445
446 namespace
447 {
lcl_convertColor(::boost::optional<::Color> const & i_color,Any & o_colorValue)448 void lcl_convertColor( ::boost::optional< ::Color > const & i_color, Any & o_colorValue )
449 {
450 if ( !i_color )
451 o_colorValue.clear();
452 else
453 o_colorValue <<= i_color->GetColor();
454 }
455 }
456
getProperty(const::rtl::OUString & PropertyName)457 Any SVTXGridControl::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException)
458 {
459 ::vos::OGuard aGuard( GetMutex() );
460
461 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
462 ENSURE_OR_RETURN( pTable != NULL, "SVTXGridControl::getProperty: no control (anymore)!", Any() );
463
464 Any aPropertyValue;
465
466 const sal_uInt16 nPropId = GetPropertyId( PropertyName );
467 switch(nPropId)
468 {
469 case BASEPROPERTY_GRID_SELECTIONMODE:
470 {
471 SelectionType eSelectionType;
472
473 SelectionMode eSelMode = pTable->getSelEngine()->GetSelectionMode();
474 switch( eSelMode )
475 {
476 case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break;
477 case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break;
478 case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break;
479 default: eSelectionType = SelectionType_NONE; break;
480 }
481 aPropertyValue <<= eSelectionType;
482 break;
483 }
484
485 case BASEPROPERTY_GRID_SHOWROWHEADER:
486 aPropertyValue <<= sal_Bool( m_pTableModel->hasRowHeaders() );
487 break;
488
489 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
490 aPropertyValue <<= sal_Bool( m_pTableModel->hasColumnHeaders() );
491 break;
492
493 case BASEPROPERTY_GRID_DATAMODEL:
494 aPropertyValue <<= m_pTableModel->getDataModel();
495 break;
496
497 case BASEPROPERTY_GRID_COLUMNMODEL:
498 aPropertyValue <<= m_pTableModel->getColumnModel();
499 break;
500
501 case BASEPROPERTY_HSCROLL:
502 {
503 sal_Bool const bHasScrollbar = ( m_pTableModel->getHorizontalScrollbarVisibility() != ScrollbarShowNever );
504 aPropertyValue <<= bHasScrollbar;
505 break;
506 }
507
508 case BASEPROPERTY_VSCROLL:
509 {
510 sal_Bool const bHasScrollbar = ( m_pTableModel->getVerticalScrollbarVisibility() != ScrollbarShowNever );
511 aPropertyValue <<= bHasScrollbar;
512 break;
513 }
514
515 case BASEPROPERTY_USE_GRID_LINES:
516 {
517 GridTableRenderer* pGridRenderer = dynamic_cast< GridTableRenderer* >(
518 m_pTableModel->getRenderer().get() );
519 ENSURE_OR_BREAK( pGridRenderer != NULL, "SVTXGridControl::getProperty(UseGridLines): invalid renderer!" );
520 aPropertyValue <<= pGridRenderer->useGridLines();
521 }
522 break;
523
524 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS:
525 {
526 ::boost::optional< ::std::vector< ::Color > > aColors( m_pTableModel->getRowBackgroundColors() );
527 if ( !aColors )
528 aPropertyValue.clear();
529 else
530 {
531 Sequence< UnoColor > aAPIColors( aColors->size() );
532 for ( size_t i=0; i<aColors->size(); ++i )
533 {
534 aAPIColors[i] = aColors->at(i).GetColor();
535 }
536 aPropertyValue <<= aAPIColors;
537 }
538 }
539 break;
540
541 case BASEPROPERTY_GRID_LINE_COLOR:
542 lcl_convertColor( m_pTableModel->getLineColor(), aPropertyValue );
543 break;
544
545 case BASEPROPERTY_GRID_HEADER_BACKGROUND:
546 lcl_convertColor( m_pTableModel->getHeaderBackgroundColor(), aPropertyValue );
547 break;
548
549 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR:
550 lcl_convertColor( m_pTableModel->getHeaderTextColor(), aPropertyValue );
551 break;
552
553 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
554 lcl_convertColor( m_pTableModel->getActiveSelectionBackColor(), aPropertyValue );
555 break;
556
557 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
558 lcl_convertColor( m_pTableModel->getInactiveSelectionBackColor(), aPropertyValue );
559 break;
560
561 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
562 lcl_convertColor( m_pTableModel->getActiveSelectionTextColor(), aPropertyValue );
563 break;
564
565 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
566 lcl_convertColor( m_pTableModel->getInactiveSelectionTextColor(), aPropertyValue );
567 break;
568
569 case BASEPROPERTY_TEXTCOLOR:
570 lcl_convertColor( m_pTableModel->getTextColor(), aPropertyValue );
571 break;
572
573 case BASEPROPERTY_TEXTLINECOLOR:
574 lcl_convertColor( m_pTableModel->getTextLineColor(), aPropertyValue );
575 break;
576
577 default:
578 aPropertyValue = VCLXWindow::getProperty( PropertyName );
579 break;
580 }
581
582 return aPropertyValue;
583 }
584
ImplGetPropertyIds(std::list<sal_uInt16> & rIds)585 void SVTXGridControl::ImplGetPropertyIds( std::list< sal_uInt16 > &rIds )
586 {
587 PushPropertyIds( rIds,
588 BASEPROPERTY_GRID_SHOWROWHEADER,
589 BASEPROPERTY_GRID_SHOWCOLUMNHEADER,
590 BASEPROPERTY_GRID_DATAMODEL,
591 BASEPROPERTY_GRID_COLUMNMODEL,
592 BASEPROPERTY_GRID_SELECTIONMODE,
593 BASEPROPERTY_GRID_HEADER_BACKGROUND,
594 BASEPROPERTY_GRID_HEADER_TEXT_COLOR,
595 BASEPROPERTY_GRID_LINE_COLOR,
596 BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS,
597 BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR,
598 BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR,
599 BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR,
600 BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR,
601 0
602 );
603 VCLXWindow::ImplGetPropertyIds( rIds, true );
604 }
605
606 //----------------------------------------------------------------------------------------------------------------------
rowsInserted(const GridDataEvent & i_event)607 void SAL_CALL SVTXGridControl::rowsInserted( const GridDataEvent& i_event ) throw (RuntimeException)
608 {
609 ::vos::OGuard aGuard( GetMutex() );
610 m_pTableModel->notifyRowsInserted( i_event );
611 }
612
613 //----------------------------------------------------------------------------------------------------------------------
614 void SAL_CALL//----------------------------------------------------------------------------------------------------------------------
rowsRemoved(const GridDataEvent & i_event)615 SVTXGridControl::rowsRemoved( const GridDataEvent& i_event ) throw (RuntimeException)
616 {
617 ::vos::OGuard aGuard( GetMutex() );
618 m_pTableModel->notifyRowsRemoved( i_event );
619 }
620
621 //----------------------------------------------------------------------------------------------------------------------
dataChanged(const GridDataEvent & i_event)622 void SAL_CALL SVTXGridControl::dataChanged( const GridDataEvent& i_event ) throw (RuntimeException)
623 {
624 ::vos::OGuard aGuard( GetMutex() );
625
626 m_pTableModel->notifyDataChanged( i_event );
627
628 // if the data model is sortable, a dataChanged event is also fired in case the sort order changed.
629 // So, just in case, invalidate the column header area, too.
630 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
631 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::dataChanged: no control (anymore)!" );
632 pTable->getTableControlInterface().invalidate( TableAreaColumnHeaders );
633 }
634
635 //----------------------------------------------------------------------------------------------------------------------
rowHeadingChanged(const GridDataEvent & i_event)636 void SAL_CALL SVTXGridControl::rowHeadingChanged( const GridDataEvent& i_event ) throw (RuntimeException)
637 {
638 ::vos::OGuard aGuard( GetMutex() );
639 OSL_UNUSED( i_event );
640
641 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
642 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::rowHeadingChanged: no control (anymore)!" );
643
644 // TODO: we could do better than this - invalidate the header area only
645 pTable->getTableControlInterface().invalidate( TableAreaRowHeaders );
646 }
647
648 //----------------------------------------------------------------------------------------------------------------------
elementInserted(const ContainerEvent & i_event)649 void SAL_CALL SVTXGridControl::elementInserted( const ContainerEvent& i_event ) throw (RuntimeException)
650 {
651 ::vos::OGuard aGuard( GetMutex() );
652
653 Reference< XGridColumn > const xGridColumn( i_event.Element, UNO_QUERY_THROW );
654
655 sal_Int32 nIndex( m_pTableModel->getColumnCount() );
656 OSL_VERIFY( i_event.Accessor >>= nIndex );
657 m_pTableModel->insertColumn( nIndex, xGridColumn );
658 }
659
660 //----------------------------------------------------------------------------------------------------------------------
elementRemoved(const ContainerEvent & i_event)661 void SAL_CALL SVTXGridControl::elementRemoved( const ContainerEvent& i_event ) throw (RuntimeException)
662 {
663 ::vos::OGuard aGuard( GetMutex() );
664
665 sal_Int32 nIndex( -1 );
666 OSL_VERIFY( i_event.Accessor >>= nIndex );
667 m_pTableModel->removeColumn( nIndex );
668 }
669
670 //----------------------------------------------------------------------------------------------------------------------
elementReplaced(const ContainerEvent & i_event)671 void SAL_CALL SVTXGridControl::elementReplaced( const ContainerEvent& i_event ) throw (RuntimeException)
672 {
673 OSL_ENSURE( false, "SVTXGridControl::elementReplaced: not implemented!" );
674 // at the moment, the XGridColumnModel API does not allow replacing columns
675 OSL_UNUSED( i_event );
676 // TODO: replace the respective column in our table model
677 }
678
679
680 //----------------------------------------------------------------------------------------------------------------------
disposing(const EventObject & Source)681 void SAL_CALL SVTXGridControl::disposing( const EventObject& Source ) throw(RuntimeException)
682 {
683 VCLXWindow::disposing( Source );
684 }
685
686 //----------------------------------------------------------------------------------------------------------------------
selectRow(::sal_Int32 i_rowIndex)687 void SAL_CALL SVTXGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
688 {
689 ::vos::OGuard aGuard( GetMutex() );
690
691 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
692 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectRow: no control (anymore)!" );
693
694 impl_checkRowIndex_throw( *pTable, i_rowIndex );
695
696 pTable->SelectRow( i_rowIndex, true );
697 }
698
699 //----------------------------------------------------------------------------------------------------------------------
selectAllRows()700 void SAL_CALL SVTXGridControl::selectAllRows() throw (RuntimeException)
701 {
702 ::vos::OGuard aGuard( GetMutex() );
703
704 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
705 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::selectAllRows: no control (anymore)!" );
706
707 pTable->SelectAllRows( true );
708 }
709
710 //----------------------------------------------------------------------------------------------------------------------
deselectRow(::sal_Int32 i_rowIndex)711 void SAL_CALL SVTXGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException )
712 {
713 ::vos::OGuard aGuard( GetMutex() );
714
715 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
716 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectRow: no control (anymore)!" );
717
718 impl_checkRowIndex_throw( *pTable, i_rowIndex );
719
720 pTable->SelectRow( i_rowIndex, false );
721 }
722
723 //----------------------------------------------------------------------------------------------------------------------
deselectAllRows()724 void SAL_CALL SVTXGridControl::deselectAllRows() throw (RuntimeException)
725 {
726 ::vos::OGuard aGuard( GetMutex() );
727
728 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
729 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::deselectAllRows: no control (anymore)!" );
730
731 pTable->SelectAllRows( false );
732 }
733
734 //----------------------------------------------------------------------------------------------------------------------
getSelectedRows()735 Sequence< ::sal_Int32 > SAL_CALL SVTXGridControl::getSelectedRows() throw (RuntimeException)
736 {
737 ::vos::OGuard aGuard( GetMutex() );
738
739 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
740 ENSURE_OR_RETURN( pTable, "SVTXGridControl::getSelectedRows: no control (anymore)!", Sequence< sal_Int32 >() );
741
742 sal_Int32 selectionCount = pTable->GetSelectedRowCount();
743 Sequence< sal_Int32 > selectedRows( selectionCount );
744 for ( sal_Int32 i=0; i<selectionCount; ++i )
745 selectedRows[i] = pTable->GetSelectedRowIndex(i);
746 return selectedRows;
747 }
748
749 //----------------------------------------------------------------------------------------------------------------------
hasSelectedRows()750 ::sal_Bool SAL_CALL SVTXGridControl::hasSelectedRows() throw (RuntimeException)
751 {
752 ::vos::OGuard aGuard( GetMutex() );
753
754 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
755 ENSURE_OR_RETURN( pTable, "SVTXGridControl::hasSelectedRows: no control (anymore)!", sal_True );
756
757 return pTable->GetSelectedRowCount() > 0;
758 }
759
760 //----------------------------------------------------------------------------------------------------------------------
isRowSelected(::sal_Int32 index)761 ::sal_Bool SAL_CALL SVTXGridControl::isRowSelected( ::sal_Int32 index ) throw (RuntimeException)
762 {
763 ::vos::OGuard aGuard( GetMutex() );
764
765 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
766 ENSURE_OR_RETURN( pTable, "SVTXGridControl::isRowSelected: no control (anymore)!", sal_False );
767
768 return pTable->IsRowSelected( index );
769 }
770
771 //----------------------------------------------------------------------------------------------------------------------
dispose()772 void SVTXGridControl::dispose() throw(RuntimeException)
773 {
774 EventObject aObj;
775 aObj.Source = (::cppu::OWeakObject*)this;
776 m_aSelectionListeners.disposeAndClear( aObj );
777 VCLXWindow::dispose();
778 }
779
780 //----------------------------------------------------------------------------------------------------------------------
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)781 void SVTXGridControl::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
782 {
783 ::vos::OGuard aGuard( GetMutex() );
784
785 Reference< XWindow > xKeepAlive( this );
786
787 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
788 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ProcessWindowEvent: no control (anymore)!" );
789
790 bool handled = false;
791 switch ( rVclWindowEvent.GetId() )
792 {
793 case VCLEVENT_TABLEROW_SELECT:
794 {
795 if ( m_aSelectionListeners.getLength() )
796 ImplCallItemListeners();
797 handled = true;
798 }
799 break;
800
801 case VCLEVENT_CONTROL_GETFOCUS:
802 {
803 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
804 // works when the control is used outside the UNO context
805 if ( pTable->GetRowCount()>0 )
806 {
807 pTable->commitCellEventIfAccessibleAlive(
808 AccessibleEventId::STATE_CHANGED,
809 makeAny( AccessibleStateType::FOCUSED ),
810 Any()
811 );
812 pTable->commitTableEventIfAccessibleAlive(
813 AccessibleEventId::ACTIVE_DESCENDANT_CHANGED,
814 Any(),
815 Any()
816 );
817 }
818 else
819 {
820 pTable->commitTableEventIfAccessibleAlive(
821 AccessibleEventId::STATE_CHANGED,
822 makeAny( AccessibleStateType::FOCUSED ),
823 Any()
824 );
825 }
826 }
827 break;
828
829 case VCLEVENT_CONTROL_LOSEFOCUS:
830 {
831 // TODO: this doesn't belong here. It belongs into the TableControl/_Impl, so A11Y also
832 // works when the control is used outside the UNO context
833 if ( pTable->GetRowCount()>0 )
834 {
835 pTable->commitCellEventIfAccessibleAlive(
836 AccessibleEventId::STATE_CHANGED,
837 Any(),
838 makeAny( AccessibleStateType::FOCUSED )
839 );
840 }
841 else
842 {
843 pTable->commitTableEventIfAccessibleAlive(
844 AccessibleEventId::STATE_CHANGED,
845 Any(),
846 makeAny( AccessibleStateType::FOCUSED )
847 );
848 }
849 }
850 break;
851 }
852
853 if ( !handled )
854 VCLXWindow::ProcessWindowEvent( rVclWindowEvent );
855 }
856
857 //----------------------------------------------------------------------------------------------------------------------
setEnable(sal_Bool bEnable)858 void SVTXGridControl::setEnable( sal_Bool bEnable ) throw(::com::sun::star::uno::RuntimeException)
859 {
860 ::vos::OGuard aGuard( GetMutex() );
861 m_pTableModel->setEnabled( bEnable );
862 Window * pWindow = GetWindow();
863 if ( pWindow )
864 {
865 pWindow->Enable( bEnable, sal_True );
866 pWindow->EnableInput( bEnable );
867 pWindow->Invalidate();
868 }
869 }
870
871 //----------------------------------------------------------------------------------------------------------------------
ImplCallItemListeners()872 void SVTXGridControl::ImplCallItemListeners()
873 {
874 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
875 ENSURE_OR_RETURN_VOID( pTable, "SVTXGridControl::ImplCallItemListeners: no control (anymore)!" );
876
877 if ( m_aSelectionListeners.getLength() )
878 {
879 GridSelectionEvent aEvent;
880 aEvent.Source = (::cppu::OWeakObject*)this;
881
882 sal_Int32 const nSelectedRowCount( pTable->GetSelectedRowCount() );
883 aEvent.SelectedRowIndexes.realloc( nSelectedRowCount );
884 for ( sal_Int32 i=0; i<nSelectedRowCount; ++i )
885 aEvent.SelectedRowIndexes[i] = pTable->GetSelectedRowIndex( i );
886 m_aSelectionListeners.selectionChanged( aEvent );
887 }
888 }
889
890 //----------------------------------------------------------------------------------------------------------------------
impl_updateColumnsFromModel_nothrow()891 void SVTXGridControl::impl_updateColumnsFromModel_nothrow()
892 {
893 Reference< XGridColumnModel > const xColumnModel( m_pTableModel->getColumnModel() );
894 ENSURE_OR_RETURN_VOID( xColumnModel.is(), "no model!" );
895 TableControl* pTable = dynamic_cast< TableControl* >( GetWindow() );
896 ENSURE_OR_RETURN_VOID( pTable != NULL, "no table!" );
897
898 try
899 {
900 const Sequence< Reference< XGridColumn > > columns = xColumnModel->getColumns();
901 for ( const Reference< XGridColumn >* colRef = columns.getConstArray();
902 colRef != columns.getConstArray() + columns.getLength();
903 ++colRef
904 )
905 {
906 ENSURE_OR_CONTINUE( colRef->is(), "illegal column!" );
907
908 m_pTableModel->appendColumn( *colRef );
909 }
910 }
911 catch( const Exception& )
912 {
913 DBG_UNHANDLED_EXCEPTION();
914 }
915 }
916