Line data Source code
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 "unocontroltablemodel.hxx"
21 : #include "unogridcolumnfacade.hxx"
22 :
23 : #include "svtools/table/defaultinputhandler.hxx"
24 : #include "svtools/table/gridtablerenderer.hxx"
25 : #include "svtools/table/tablecontrol.hxx"
26 :
27 : #include <com/sun/star/awt/grid/XGridColumn.hpp>
28 : #include <com/sun/star/view/SelectionType.hpp>
29 : #include <com/sun/star/awt/grid/XGridColumnListener.hpp>
30 : #include <com/sun/star/awt/grid/XSortableGridData.hpp>
31 :
32 : #include <comphelper/stlunosequence.hxx>
33 : #include <cppuhelper/weakref.hxx>
34 : #include <tools/debug.hxx>
35 : #include <tools/diagnose_ex.h>
36 : #include <vcl/svapp.hxx>
37 : #include <osl/mutex.hxx>
38 :
39 : // .....................................................................................................................
40 : namespace svt { namespace table
41 : {
42 : // .....................................................................................................................
43 :
44 : using ::com::sun::star::uno::Reference;
45 : using ::com::sun::star::uno::RuntimeException;
46 : using ::com::sun::star::uno::Sequence;
47 : using ::com::sun::star::uno::UNO_QUERY_THROW;
48 : using ::com::sun::star::uno::UNO_QUERY;
49 : using ::com::sun::star::awt::grid::XGridColumn;
50 : using ::com::sun::star::uno::XInterface;
51 : using ::com::sun::star::uno::Exception;
52 : using ::com::sun::star::awt::grid::XGridColumnListener;
53 : using ::com::sun::star::lang::EventObject;
54 : using ::com::sun::star::awt::grid::GridColumnEvent;
55 : using ::com::sun::star::awt::grid::XGridDataModel;
56 : using ::com::sun::star::awt::grid::XGridColumnModel;
57 : using ::com::sun::star::uno::Any;
58 : using ::com::sun::star::style::HorizontalAlignment_LEFT;
59 : using ::com::sun::star::style::HorizontalAlignment;
60 : using ::com::sun::star::style::VerticalAlignment_TOP;
61 : using ::com::sun::star::style::VerticalAlignment;
62 : using ::com::sun::star::uno::WeakReference;
63 : using ::com::sun::star::awt::grid::GridDataEvent;
64 : using ::com::sun::star::awt::grid::XSortableGridData;
65 : using ::com::sun::star::beans::Pair;
66 :
67 : //==================================================================================================================
68 : //= UnoControlTableModel_Impl
69 : //==================================================================================================================
70 : typedef ::std::vector< PTableModelListener > ModellListeners;
71 : typedef ::std::vector< PColumnModel > ColumnModels;
72 1 : struct UnoControlTableModel_Impl
73 : {
74 : ColumnModels aColumns;
75 : bool bHasColumnHeaders;
76 : bool bHasRowHeaders;
77 : ScrollbarVisibility eVScrollMode;
78 : ScrollbarVisibility eHScrollMode;
79 : PTableRenderer pRenderer;
80 : PTableInputHandler pInputHandler;
81 : TableMetrics nRowHeight;
82 : TableMetrics nColumnHeaderHeight;
83 : TableMetrics nRowHeaderWidth;
84 : ::boost::optional< ::Color > m_aGridLineColor;
85 : ::boost::optional< ::Color > m_aHeaderBackgroundColor;
86 : ::boost::optional< ::Color > m_aHeaderTextColor;
87 : ::boost::optional< ::Color > m_aActiveSelectionBackColor;
88 : ::boost::optional< ::Color > m_aInactiveSelectionBackColor;
89 : ::boost::optional< ::Color > m_aActiveSelectionTextColor;
90 : ::boost::optional< ::Color > m_aInactiveSelectionTextColor;
91 : ::boost::optional< ::Color > m_aTextColor;
92 : ::boost::optional< ::Color > m_aTextLineColor;
93 : ::boost::optional< ::std::vector< ::Color > > m_aRowColors;
94 : VerticalAlignment m_eVerticalAlign;
95 : ModellListeners m_aListeners;
96 : WeakReference< XGridDataModel > m_aDataModel;
97 : WeakReference< XGridColumnModel > m_aColumnModel;
98 :
99 1 : UnoControlTableModel_Impl()
100 : :aColumns ( )
101 : ,bHasColumnHeaders ( true )
102 : ,bHasRowHeaders ( false )
103 : ,eVScrollMode ( ScrollbarShowNever )
104 : ,eHScrollMode ( ScrollbarShowNever )
105 : ,pRenderer ( )
106 : ,pInputHandler ( )
107 : ,nRowHeight ( 10 )
108 : ,nColumnHeaderHeight ( 10 )
109 : ,nRowHeaderWidth ( 10 )
110 : ,m_aGridLineColor ( )
111 : ,m_aHeaderBackgroundColor ( )
112 : ,m_aHeaderTextColor ( )
113 : ,m_aActiveSelectionBackColor ( )
114 : ,m_aInactiveSelectionBackColor ( )
115 : ,m_aActiveSelectionTextColor ( )
116 : ,m_aInactiveSelectionTextColor ( )
117 : ,m_aTextColor ( )
118 : ,m_aTextLineColor ( )
119 : ,m_aRowColors ( )
120 1 : ,m_eVerticalAlign ( VerticalAlignment_TOP )
121 : {
122 1 : }
123 : };
124 :
125 : //==================================================================================================================
126 : //= UnoControlTableModel
127 : //==================================================================================================================
128 : #ifdef DBG_UTIL
129 : const char* UnoControlTableModel_checkInvariants( const void* _pInstance )
130 : {
131 : return static_cast< const UnoControlTableModel* >( _pInstance )->checkInvariants();
132 : }
133 :
134 : //------------------------------------------------------------------------------------------------------------------
135 : const char* UnoControlTableModel::checkInvariants() const
136 : {
137 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
138 : if ( !xDataModel.is() )
139 : return "data model anymore";
140 :
141 : // TODO: more?
142 :
143 : return NULL;
144 : }
145 : #endif
146 :
147 : #define DBG_CHECK_ME() \
148 : DBG_TESTSOLARMUTEX(); \
149 : DBG_CHKTHIS( UnoControlTableModel, UnoControlTableModel_checkInvariants )
150 :
151 : //------------------------------------------------------------------------------------------------------------------
152 : DBG_NAME( UnoControlTableModel )
153 1 : UnoControlTableModel::UnoControlTableModel()
154 1 : :m_pImpl( new UnoControlTableModel_Impl )
155 : {
156 : DBG_CTOR( UnoControlTableModel, UnoControlTableModel_checkInvariants );
157 1 : m_pImpl->bHasColumnHeaders = true;
158 1 : m_pImpl->bHasRowHeaders = false;
159 1 : m_pImpl->pRenderer.reset( new GridTableRenderer( *this ) );
160 1 : m_pImpl->pInputHandler.reset( new DefaultInputHandler );
161 1 : }
162 :
163 : //------------------------------------------------------------------------------------------------------------------
164 3 : UnoControlTableModel::~UnoControlTableModel()
165 : {
166 : DBG_DTOR( UnoControlTableModel, UnoControlTableModel_checkInvariants );
167 1 : DELETEZ( m_pImpl );
168 2 : }
169 :
170 : //------------------------------------------------------------------------------------------------------------------
171 110 : TableSize UnoControlTableModel::getColumnCount() const
172 : {
173 : DBG_CHECK_ME();
174 110 : return (TableSize)m_pImpl->aColumns.size();
175 : }
176 :
177 : //------------------------------------------------------------------------------------------------------------------
178 12 : TableSize UnoControlTableModel::getRowCount() const
179 : {
180 : DBG_CHECK_ME();
181 :
182 12 : TableSize nRowCount = 0;
183 : try
184 : {
185 12 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
186 12 : ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" );
187 12 : nRowCount = xDataModel->getRowCount();
188 : }
189 0 : catch( const Exception& )
190 : {
191 : DBG_UNHANDLED_EXCEPTION();
192 : }
193 12 : return nRowCount;
194 : }
195 :
196 : //------------------------------------------------------------------------------------------------------------------
197 3 : bool UnoControlTableModel::hasColumnHeaders() const
198 : {
199 : DBG_CHECK_ME();
200 3 : return m_pImpl->bHasColumnHeaders;
201 : }
202 :
203 : //------------------------------------------------------------------------------------------------------------------
204 25 : bool UnoControlTableModel::hasRowHeaders() const
205 : {
206 : DBG_CHECK_ME();
207 25 : return m_pImpl->bHasRowHeaders;
208 : }
209 :
210 : //------------------------------------------------------------------------------------------------------------------
211 1 : void UnoControlTableModel::setRowHeaders(bool _bRowHeaders)
212 : {
213 : DBG_CHECK_ME();
214 1 : if ( m_pImpl->bHasRowHeaders == _bRowHeaders )
215 2 : return;
216 :
217 0 : m_pImpl->bHasRowHeaders = _bRowHeaders;
218 0 : impl_notifyTableMetricsChanged();
219 : }
220 :
221 : //------------------------------------------------------------------------------------------------------------------
222 1 : void UnoControlTableModel::setColumnHeaders(bool _bColumnHeaders)
223 : {
224 : DBG_CHECK_ME();
225 1 : if ( m_pImpl->bHasColumnHeaders == _bColumnHeaders )
226 2 : return;
227 :
228 0 : m_pImpl->bHasColumnHeaders = _bColumnHeaders;
229 0 : impl_notifyTableMetricsChanged();
230 : }
231 :
232 : //------------------------------------------------------------------------------------------------------------------
233 0 : bool UnoControlTableModel::isCellEditable( ColPos col, RowPos row ) const
234 : {
235 : DBG_CHECK_ME();
236 : (void)col;
237 : (void)row;
238 0 : return false;
239 : }
240 :
241 : //------------------------------------------------------------------------------------------------------------------
242 56 : PColumnModel UnoControlTableModel::getColumnModel( ColPos column )
243 : {
244 : DBG_CHECK_ME();
245 56 : ENSURE_OR_RETURN( ( column >= 0 ) && ( column < getColumnCount() ),
246 : "DefaultTableModel::getColumnModel: invalid index!", PColumnModel() );
247 56 : return m_pImpl->aColumns[ column ];
248 : }
249 :
250 : //------------------------------------------------------------------------------------------------------------------
251 0 : void UnoControlTableModel::appendColumn( Reference< XGridColumn > const & i_column )
252 : {
253 : DBG_CHECK_ME();
254 0 : insertColumn( m_pImpl->aColumns.size(), i_column );
255 0 : }
256 :
257 : //------------------------------------------------------------------------------------------------------------------
258 3 : void UnoControlTableModel::insertColumn( ColPos const i_position, Reference< XGridColumn > const & i_column )
259 : {
260 : DBG_CHECK_ME();
261 6 : ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( size_t( i_position ) <= m_pImpl->aColumns.size() ),
262 : "UnoControlTableModel::insertColumn: illegal position!" );
263 :
264 3 : const PColumnModel pColumn( new UnoGridColumnFacade( *this, i_column ) );
265 3 : m_pImpl->aColumns.insert( m_pImpl->aColumns.begin() + i_position, pColumn );
266 :
267 : // notify listeners
268 6 : ModellListeners aListeners( m_pImpl->m_aListeners );
269 18 : for ( ModellListeners::const_iterator loop = aListeners.begin();
270 12 : loop != aListeners.end();
271 : ++loop
272 : )
273 : {
274 3 : (*loop)->columnInserted( i_position );
275 3 : }
276 : }
277 :
278 : //------------------------------------------------------------------------------------------------------------------
279 1 : void UnoControlTableModel::removeColumn( ColPos const i_position )
280 : {
281 : DBG_CHECK_ME();
282 2 : ENSURE_OR_RETURN_VOID( ( i_position >= 0 ) && ( size_t( i_position ) <= m_pImpl->aColumns.size() ),
283 : "UnoControlTableModel::removeColumn: illegal position!" );
284 :
285 : // remove the column
286 1 : ColumnModels::iterator pos = m_pImpl->aColumns.begin() + i_position;
287 1 : const PColumnModel pColumn = *pos;
288 1 : m_pImpl->aColumns.erase( pos );
289 :
290 : // notify listeners
291 2 : ModellListeners aListeners( m_pImpl->m_aListeners );
292 6 : for ( ModellListeners::const_iterator loop = aListeners.begin();
293 4 : loop != aListeners.end();
294 : ++loop
295 : )
296 : {
297 1 : (*loop)->columnRemoved( i_position );
298 : }
299 :
300 : // dispose the column
301 1 : UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() );
302 : OSL_ENSURE( pColumnImpl != NULL, "UnoControlTableModel::removeColumn: illegal column implementation!" );
303 1 : if ( pColumnImpl )
304 2 : pColumnImpl->dispose();
305 : }
306 :
307 : //------------------------------------------------------------------------------------------------------------------
308 1 : void UnoControlTableModel::removeAllColumns()
309 : {
310 : DBG_CHECK_ME();
311 1 : if ( m_pImpl->aColumns.empty() )
312 2 : return;
313 :
314 : // dispose the column instances
315 0 : for ( ColumnModels::const_iterator col = m_pImpl->aColumns.begin();
316 0 : col != m_pImpl->aColumns.end();
317 : ++col
318 : )
319 : {
320 0 : UnoGridColumnFacade* pColumn = dynamic_cast< UnoGridColumnFacade* >( col->get() );
321 0 : if ( !pColumn )
322 : {
323 : SAL_WARN( "svtools.uno", "UnoControlTableModel::removeAllColumns: illegal column implementation!" );
324 0 : continue;
325 : }
326 :
327 0 : pColumn->dispose();
328 : }
329 0 : m_pImpl->aColumns.clear();
330 :
331 : // notify listeners
332 0 : ModellListeners aListeners( m_pImpl->m_aListeners );
333 0 : for ( ModellListeners::const_iterator loop = aListeners.begin();
334 0 : loop != aListeners.end();
335 : ++loop
336 : )
337 : {
338 0 : (*loop)->allColumnsRemoved();
339 0 : }
340 : }
341 :
342 : //------------------------------------------------------------------------------------------------------------------
343 0 : void UnoControlTableModel::impl_notifyTableMetricsChanged() const
344 : {
345 0 : ModellListeners aListeners( m_pImpl->m_aListeners );
346 0 : for ( ModellListeners::const_iterator loop = aListeners.begin();
347 0 : loop != aListeners.end();
348 : ++loop
349 : )
350 : {
351 0 : (*loop)->tableMetricsChanged();
352 0 : }
353 0 : }
354 :
355 : //------------------------------------------------------------------------------------------------------------------
356 3 : PTableRenderer UnoControlTableModel::getRenderer() const
357 : {
358 : DBG_CHECK_ME();
359 3 : return m_pImpl->pRenderer;
360 : }
361 :
362 : //------------------------------------------------------------------------------------------------------------------
363 1 : PTableInputHandler UnoControlTableModel::getInputHandler() const
364 : {
365 : DBG_CHECK_ME();
366 1 : return m_pImpl->pInputHandler;
367 : }
368 :
369 : //------------------------------------------------------------------------------------------------------------------
370 1 : TableMetrics UnoControlTableModel::getRowHeight() const
371 : {
372 : DBG_CHECK_ME();
373 1 : return m_pImpl->nRowHeight;
374 : }
375 :
376 : //------------------------------------------------------------------------------------------------------------------
377 1 : void UnoControlTableModel::setRowHeight(TableMetrics _nRowHeight)
378 : {
379 : DBG_CHECK_ME();
380 1 : if ( m_pImpl->nRowHeight == _nRowHeight )
381 2 : return;
382 :
383 0 : m_pImpl->nRowHeight = _nRowHeight;
384 0 : impl_notifyTableMetricsChanged();
385 : }
386 :
387 : //------------------------------------------------------------------------------------------------------------------
388 1 : TableMetrics UnoControlTableModel::getColumnHeaderHeight() const
389 : {
390 : DBG_CHECK_ME();
391 : DBG_ASSERT( hasColumnHeaders(), "DefaultTableModel::getColumnHeaderHeight: invalid call!" );
392 1 : return m_pImpl->nColumnHeaderHeight;
393 : }
394 :
395 : //------------------------------------------------------------------------------------------------------------------
396 0 : TableMetrics UnoControlTableModel::getRowHeaderWidth() const
397 : {
398 : DBG_CHECK_ME();
399 : DBG_ASSERT( hasRowHeaders(), "DefaultTableModel::getRowHeaderWidth: invalid call!" );
400 0 : return m_pImpl->nRowHeaderWidth;
401 : }
402 : //------------------------------------------------------------------------------------------------------------------
403 1 : void UnoControlTableModel::setColumnHeaderHeight(TableMetrics _nHeight)
404 : {
405 : DBG_CHECK_ME();
406 1 : if ( m_pImpl->nColumnHeaderHeight == _nHeight )
407 2 : return;
408 :
409 0 : m_pImpl->nColumnHeaderHeight = _nHeight;
410 0 : impl_notifyTableMetricsChanged();
411 : }
412 :
413 : //------------------------------------------------------------------------------------------------------------------
414 1 : void UnoControlTableModel::setRowHeaderWidth(TableMetrics _nWidth)
415 : {
416 : DBG_CHECK_ME();
417 1 : if ( m_pImpl->nRowHeaderWidth == _nWidth )
418 2 : return;
419 :
420 0 : m_pImpl->nRowHeaderWidth = _nWidth;
421 0 : impl_notifyTableMetricsChanged();
422 : }
423 :
424 : //------------------------------------------------------------------------------------------------------------------
425 20 : ScrollbarVisibility UnoControlTableModel::getVerticalScrollbarVisibility() const
426 : {
427 : DBG_CHECK_ME();
428 20 : return m_pImpl->eVScrollMode;
429 : }
430 :
431 : //------------------------------------------------------------------------------------------------------------------
432 10 : ScrollbarVisibility UnoControlTableModel::getHorizontalScrollbarVisibility() const
433 : {
434 : DBG_CHECK_ME();
435 10 : return m_pImpl->eHScrollMode;
436 : }
437 :
438 : //------------------------------------------------------------------------------------------------------------------
439 1 : void UnoControlTableModel::addTableModelListener( const PTableModelListener& i_listener )
440 : {
441 : DBG_CHECK_ME();
442 2 : ENSURE_OR_RETURN_VOID( !!i_listener, "illegal NULL listener" );
443 1 : m_pImpl->m_aListeners.push_back( i_listener );
444 : }
445 :
446 : //------------------------------------------------------------------------------------------------------------------
447 1 : void UnoControlTableModel::removeTableModelListener( const PTableModelListener& i_listener )
448 : {
449 : DBG_CHECK_ME();
450 3 : for ( ModellListeners::iterator lookup = m_pImpl->m_aListeners.begin();
451 2 : lookup != m_pImpl->m_aListeners.end();
452 : ++lookup
453 : )
454 : {
455 1 : if ( *lookup == i_listener )
456 : {
457 1 : m_pImpl->m_aListeners.erase( lookup );
458 2 : return;
459 : }
460 : }
461 : OSL_ENSURE( false, "UnoControlTableModel::removeTableModelListener: listener is not registered - sure you're doing the right thing here?" );
462 : }
463 :
464 : //------------------------------------------------------------------------------------------------------------------
465 1 : void UnoControlTableModel::setVerticalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const
466 : {
467 : DBG_CHECK_ME();
468 1 : m_pImpl->eVScrollMode = i_visibility;
469 1 : }
470 :
471 : //------------------------------------------------------------------------------------------------------------------
472 1 : void UnoControlTableModel::setHorizontalScrollbarVisibility( ScrollbarVisibility const i_visibility ) const
473 : {
474 : DBG_CHECK_ME();
475 1 : m_pImpl->eHScrollMode = i_visibility;
476 1 : }
477 :
478 : //------------------------------------------------------------------------------------------------------------------
479 1 : void UnoControlTableModel::setDataModel( Reference< XGridDataModel > const & i_gridDataModel )
480 : {
481 : DBG_CHECK_ME();
482 1 : m_pImpl->m_aDataModel = i_gridDataModel;
483 : // TODO: register as listener, so we're notified of row/data changes, and can multiplex them to our
484 : // own listeners
485 1 : }
486 :
487 : //------------------------------------------------------------------------------------------------------------------
488 7 : Reference< XGridDataModel > UnoControlTableModel::getDataModel() const
489 : {
490 7 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
491 7 : return xDataModel;
492 : }
493 :
494 : //------------------------------------------------------------------------------------------------------------------
495 2 : bool UnoControlTableModel::hasDataModel() const
496 : {
497 2 : return getDataModel().is();
498 : }
499 :
500 : //------------------------------------------------------------------------------------------------------------------
501 1 : void UnoControlTableModel::setColumnModel( Reference< XGridColumnModel > const & i_gridColumnModel )
502 : {
503 : DBG_CHECK_ME();
504 1 : m_pImpl->m_aColumnModel = i_gridColumnModel;
505 1 : }
506 :
507 : //------------------------------------------------------------------------------------------------------------------
508 5 : Reference< XGridColumnModel > UnoControlTableModel::getColumnModel() const
509 : {
510 5 : Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel );
511 5 : return xColumnModel;
512 : }
513 :
514 : //------------------------------------------------------------------------------------------------------------------
515 3 : bool UnoControlTableModel::hasColumnModel() const
516 : {
517 3 : return getColumnModel().is();
518 : }
519 :
520 : //------------------------------------------------------------------------------------------------------------------
521 2 : void UnoControlTableModel::getCellContent( ColPos const i_col, RowPos const i_row, Any& o_cellContent )
522 : {
523 : DBG_CHECK_ME();
524 :
525 2 : o_cellContent.clear();
526 : try
527 : {
528 2 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
529 2 : ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::getCellContent: no data model anymore!" );
530 :
531 4 : PColumnModel const pColumn = getColumnModel( i_col );
532 2 : UnoGridColumnFacade* pColumnImpl = dynamic_cast< UnoGridColumnFacade* >( pColumn.get() );
533 2 : ENSURE_OR_RETURN_VOID( pColumnImpl != NULL, "UnoControlTableModel::getCellContent: no (valid) column at this position!" );
534 2 : sal_Int32 const nDataColumnIndex = pColumnImpl->getDataColumnIndex() >= 0 ? pColumnImpl->getDataColumnIndex() : i_col;
535 :
536 2 : if ( nDataColumnIndex >= xDataModel->getColumnCount() )
537 : {
538 : // this is allowed, in case the column model has been dynamically extended, but the data model does
539 : // not (yet?) know about it.
540 : // So, handle it gracefully.
541 : #if OSL_DEBUG_LEVEL > 0
542 : {
543 : Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel );
544 : OSL_ENSURE( xColumnModel.is() && i_col < xColumnModel->getColumnCount(),
545 : "UnoControlTableModel::getCellContent: request a column's value which the ColumnModel doesn't know about!" );
546 : }
547 : #endif
548 : }
549 : else
550 : {
551 2 : o_cellContent = xDataModel->getCellData( nDataColumnIndex, i_row );
552 2 : }
553 : }
554 0 : catch( const Exception& )
555 : {
556 : DBG_UNHANDLED_EXCEPTION();
557 : }
558 : }
559 :
560 : //------------------------------------------------------------------------------------------------------------------
561 0 : void UnoControlTableModel::getCellToolTip( ColPos const i_col, RowPos const i_row, Any& o_cellToolTip )
562 : {
563 : DBG_CHECK_ME();
564 : try
565 : {
566 0 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
567 0 : ENSURE_OR_THROW( xDataModel.is(), "no data model anymore!" );
568 :
569 0 : o_cellToolTip = xDataModel->getCellToolTip( i_col, i_row );
570 : }
571 0 : catch( const Exception& )
572 : {
573 : DBG_UNHANDLED_EXCEPTION();
574 : }
575 0 : }
576 :
577 : //------------------------------------------------------------------------------------------------------------------
578 0 : Any UnoControlTableModel::getRowHeading( RowPos const i_rowPos ) const
579 : {
580 : DBG_CHECK_ME();
581 :
582 0 : Any aRowHeading;
583 :
584 0 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
585 0 : ENSURE_OR_RETURN( xDataModel.is(), "UnoControlTableModel::getRowHeading: no data model anymore!", aRowHeading );
586 :
587 : try
588 : {
589 0 : aRowHeading = xDataModel->getRowHeading( i_rowPos );
590 : }
591 0 : catch( const Exception& )
592 : {
593 : DBG_UNHANDLED_EXCEPTION();
594 : }
595 0 : return aRowHeading;
596 : }
597 :
598 : //------------------------------------------------------------------------------------------------------------------
599 : namespace
600 : {
601 9 : void lcl_setColor( Any const & i_color, ::boost::optional< ::Color > & o_convertedColor )
602 : {
603 9 : if ( !i_color.hasValue() )
604 9 : o_convertedColor.reset();
605 : else
606 : {
607 0 : sal_Int32 nColor = COL_TRANSPARENT;
608 0 : if ( i_color >>= nColor )
609 : {
610 0 : o_convertedColor.reset( ::Color( nColor ) );
611 : }
612 : else
613 : {
614 : OSL_ENSURE( false, "lcl_setColor: could not extract color value!" );
615 : }
616 : }
617 9 : }
618 : }
619 :
620 : //------------------------------------------------------------------------------------------------------------------
621 6 : ::boost::optional< ::Color > UnoControlTableModel::getLineColor() const
622 : {
623 : DBG_CHECK_ME();
624 6 : return m_pImpl->m_aGridLineColor;
625 : }
626 :
627 : //------------------------------------------------------------------------------------------------------------------
628 1 : void UnoControlTableModel::setLineColor( Any const & i_color )
629 : {
630 : DBG_CHECK_ME();
631 1 : lcl_setColor( i_color, m_pImpl->m_aGridLineColor );
632 1 : }
633 :
634 : //------------------------------------------------------------------------------------------------------------------
635 2 : ::boost::optional< ::Color > UnoControlTableModel::getHeaderBackgroundColor() const
636 : {
637 : DBG_CHECK_ME();
638 2 : return m_pImpl->m_aHeaderBackgroundColor;
639 : }
640 :
641 : //------------------------------------------------------------------------------------------------------------------
642 1 : void UnoControlTableModel::setHeaderBackgroundColor( Any const & i_color )
643 : {
644 : DBG_CHECK_ME();
645 1 : lcl_setColor( i_color, m_pImpl->m_aHeaderBackgroundColor );
646 1 : }
647 :
648 : //------------------------------------------------------------------------------------------------------------------
649 0 : ::boost::optional< ::Color > UnoControlTableModel::getHeaderTextColor() const
650 : {
651 : DBG_CHECK_ME();
652 0 : return m_pImpl->m_aHeaderTextColor;
653 : }
654 :
655 : //------------------------------------------------------------------------------------------------------------------
656 2 : ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionBackColor() const
657 : {
658 : DBG_CHECK_ME();
659 2 : return m_pImpl->m_aActiveSelectionBackColor;
660 : }
661 :
662 : //------------------------------------------------------------------------------------------------------------------
663 0 : ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionBackColor() const
664 : {
665 : DBG_CHECK_ME();
666 0 : return m_pImpl->m_aInactiveSelectionBackColor;
667 : }
668 :
669 : //------------------------------------------------------------------------------------------------------------------
670 0 : ::boost::optional< ::Color > UnoControlTableModel::getActiveSelectionTextColor() const
671 : {
672 : DBG_CHECK_ME();
673 0 : return m_pImpl->m_aActiveSelectionTextColor;
674 : }
675 :
676 : //------------------------------------------------------------------------------------------------------------------
677 0 : ::boost::optional< ::Color > UnoControlTableModel::getInactiveSelectionTextColor() const
678 : {
679 : DBG_CHECK_ME();
680 0 : return m_pImpl->m_aInactiveSelectionTextColor;
681 : }
682 :
683 : //------------------------------------------------------------------------------------------------------------------
684 1 : void UnoControlTableModel::setHeaderTextColor( Any const & i_color )
685 : {
686 : DBG_CHECK_ME();
687 1 : lcl_setColor( i_color, m_pImpl->m_aHeaderTextColor );
688 1 : }
689 :
690 : //------------------------------------------------------------------------------------------------------------------
691 1 : void UnoControlTableModel::setActiveSelectionBackColor( Any const & i_color )
692 : {
693 : DBG_CHECK_ME();
694 1 : lcl_setColor( i_color, m_pImpl->m_aActiveSelectionBackColor );
695 1 : }
696 :
697 : //------------------------------------------------------------------------------------------------------------------
698 1 : void UnoControlTableModel::setInactiveSelectionBackColor( Any const & i_color )
699 : {
700 : DBG_CHECK_ME();
701 1 : lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionBackColor );
702 1 : }
703 :
704 : //------------------------------------------------------------------------------------------------------------------
705 1 : void UnoControlTableModel::setActiveSelectionTextColor( Any const & i_color )
706 : {
707 : DBG_CHECK_ME();
708 1 : lcl_setColor( i_color, m_pImpl->m_aActiveSelectionTextColor );
709 1 : }
710 :
711 : //------------------------------------------------------------------------------------------------------------------
712 1 : void UnoControlTableModel::setInactiveSelectionTextColor( Any const & i_color )
713 : {
714 : DBG_CHECK_ME();
715 1 : lcl_setColor( i_color, m_pImpl->m_aInactiveSelectionTextColor );
716 1 : }
717 :
718 : //------------------------------------------------------------------------------------------------------------------
719 4 : ::boost::optional< ::Color > UnoControlTableModel::getTextColor() const
720 : {
721 : DBG_CHECK_ME();
722 4 : return m_pImpl->m_aTextColor;
723 : }
724 :
725 : //------------------------------------------------------------------------------------------------------------------
726 1 : void UnoControlTableModel::setTextColor( Any const & i_color )
727 : {
728 : DBG_CHECK_ME();
729 1 : lcl_setColor( i_color, m_pImpl->m_aTextColor );
730 1 : }
731 :
732 : //------------------------------------------------------------------------------------------------------------------
733 0 : ::boost::optional< ::Color > UnoControlTableModel::getTextLineColor() const
734 : {
735 : DBG_CHECK_ME();
736 0 : return m_pImpl->m_aTextColor;
737 : }
738 :
739 : //------------------------------------------------------------------------------------------------------------------
740 1 : void UnoControlTableModel::setTextLineColor( Any const & i_color )
741 : {
742 : DBG_CHECK_ME();
743 1 : lcl_setColor( i_color, m_pImpl->m_aTextLineColor );
744 1 : }
745 :
746 : //------------------------------------------------------------------------------------------------------------------
747 2 : ::boost::optional< ::std::vector< ::Color > > UnoControlTableModel::getRowBackgroundColors() const
748 : {
749 : DBG_CHECK_ME();
750 2 : return m_pImpl->m_aRowColors;
751 : }
752 :
753 : //------------------------------------------------------------------------------------------------------------------
754 1 : void UnoControlTableModel::setRowBackgroundColors( ::com::sun::star::uno::Any const & i_APIValue )
755 : {
756 : DBG_CHECK_ME();
757 1 : Sequence< ::com::sun::star::util::Color > aAPIColors;
758 1 : if ( !( i_APIValue >>= aAPIColors ) )
759 1 : m_pImpl->m_aRowColors.reset();
760 : else
761 : {
762 0 : ::std::vector< ::Color > aColors( aAPIColors.getLength() );
763 0 : for ( sal_Int32 i=0; i<aAPIColors.getLength(); ++i )
764 : {
765 0 : aColors[i] = ::Color( aAPIColors[i] );
766 : }
767 0 : m_pImpl->m_aRowColors.reset( aColors );
768 1 : }
769 1 : }
770 :
771 : //------------------------------------------------------------------------------------------------------------------
772 4 : VerticalAlignment UnoControlTableModel::getVerticalAlign() const
773 : {
774 : DBG_CHECK_ME();
775 4 : return m_pImpl->m_eVerticalAlign;
776 : }
777 :
778 : //------------------------------------------------------------------------------------------------------------------
779 0 : void UnoControlTableModel::setVerticalAlign( VerticalAlignment _xAlign )
780 : {
781 : DBG_CHECK_ME();
782 0 : m_pImpl->m_eVerticalAlign = _xAlign;
783 0 : }
784 :
785 : //------------------------------------------------------------------------------------------------------------------
786 8 : ColPos UnoControlTableModel::getColumnPos( UnoGridColumnFacade const & i_column ) const
787 : {
788 : DBG_CHECK_ME();
789 39 : for ( ColumnModels::const_iterator col = m_pImpl->aColumns.begin();
790 26 : col != m_pImpl->aColumns.end();
791 : ++col
792 : )
793 : {
794 13 : if ( &i_column == col->get() )
795 8 : return col - m_pImpl->aColumns.begin();
796 : }
797 : OSL_ENSURE( false, "UnoControlTableModel::getColumnPos: column not found!" );
798 0 : return COL_INVALID;
799 : }
800 :
801 : //------------------------------------------------------------------------------------------------------------------
802 2 : ITableDataSort* UnoControlTableModel::getSortAdapter()
803 : {
804 : DBG_CHECK_ME();
805 :
806 2 : Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY );
807 2 : if ( xSortAccess.is() )
808 2 : return this;
809 0 : return NULL;
810 : }
811 :
812 : //------------------------------------------------------------------------------------------------------------------
813 0 : void UnoControlTableModel::sortByColumn( ColPos const i_column, ColumnSortDirection const i_sortDirection )
814 : {
815 : DBG_CHECK_ME();
816 :
817 : try
818 : {
819 0 : Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW );
820 0 : xSortAccess->sortByColumn( i_column, i_sortDirection == ColumnSortAscending );
821 : }
822 0 : catch( const Exception& )
823 : {
824 : DBG_UNHANDLED_EXCEPTION();
825 : }
826 0 : }
827 :
828 : //------------------------------------------------------------------------------------------------------------------
829 2 : ColumnSort UnoControlTableModel::getCurrentSortOrder() const
830 : {
831 : DBG_CHECK_ME();
832 :
833 2 : ColumnSort currentSort;
834 : try
835 : {
836 2 : Reference< XSortableGridData > const xSortAccess( getDataModel(), UNO_QUERY_THROW );
837 2 : Pair< ::sal_Int32, ::sal_Bool > const aCurrentSortOrder( xSortAccess->getCurrentSortOrder() );
838 2 : currentSort.nColumnPos = aCurrentSortOrder.First;
839 2 : currentSort.eSortDirection = aCurrentSortOrder.Second ? ColumnSortAscending : ColumnSortDescending;
840 : }
841 0 : catch( const Exception& )
842 : {
843 : DBG_UNHANDLED_EXCEPTION();
844 : }
845 2 : return currentSort;
846 : }
847 :
848 : //--------------------------------------------------------------------
849 8 : void UnoControlTableModel::notifyColumnChange( ColPos const i_columnPos, ColumnAttributeGroup const i_attributeGroup ) const
850 : {
851 : DBG_CHECK_ME();
852 16 : ENSURE_OR_RETURN_VOID( ( i_columnPos >= 0 ) && ( i_columnPos < getColumnCount() ),
853 : "UnoControlTableModel::notifyColumnChange: invalid column index!" );
854 :
855 8 : ModellListeners aListeners( m_pImpl->m_aListeners );
856 48 : for ( ModellListeners::const_iterator loop = aListeners.begin();
857 32 : loop != aListeners.end();
858 : ++loop
859 : )
860 : {
861 8 : (*loop)->columnChanged( i_columnPos, i_attributeGroup );
862 8 : }
863 : }
864 :
865 : //------------------------------------------------------------------------------------------------------------------
866 2 : void UnoControlTableModel::notifyRowsInserted( GridDataEvent const & i_event ) const
867 : {
868 : // check sanity of the event
869 2 : ENSURE_OR_RETURN_VOID( i_event.FirstRow >= 0, "UnoControlTableModel::notifyRowsInserted: invalid first row!" );
870 2 : ENSURE_OR_RETURN_VOID( i_event.LastRow >= i_event.FirstRow, "UnoControlTableModel::notifyRowsInserted: invalid row indexes!" );
871 :
872 : // check own sanity
873 2 : Reference< XGridColumnModel > const xColumnModel( m_pImpl->m_aColumnModel );
874 2 : ENSURE_OR_RETURN_VOID( xColumnModel.is(), "UnoControlTableModel::notifyRowsInserted: no column model anymore!" );
875 :
876 4 : Reference< XGridDataModel > const xDataModel( m_pImpl->m_aDataModel );
877 2 : ENSURE_OR_RETURN_VOID( xDataModel.is(), "UnoControlTableModel::notifyRowsInserted: no data model anymore!" );
878 :
879 : // implicitly add columns to the column model
880 : // TODO: is this really a good idea?
881 2 : sal_Int32 const dataColumnCount = xDataModel->getColumnCount();
882 : OSL_ENSURE( dataColumnCount > 0, "UnoControlTableModel::notifyRowsInserted: no columns at all?" );
883 :
884 2 : sal_Int32 const modelColumnCount = xColumnModel->getColumnCount();
885 2 : if ( ( modelColumnCount == 0 ) && ( dataColumnCount > 0 ) )
886 : {
887 : // TODO: shouldn't we clear the mutexes guard for this call?
888 1 : xColumnModel->setDefaultColumns( dataColumnCount );
889 : }
890 :
891 : // multiplex the event to our own listeners
892 4 : ModellListeners aListeners( m_pImpl->m_aListeners );
893 12 : for ( ModellListeners::const_iterator loop = aListeners.begin();
894 8 : loop != aListeners.end();
895 : ++loop
896 : )
897 : {
898 2 : (*loop)->rowsInserted( i_event.FirstRow, i_event.LastRow );
899 2 : }
900 : }
901 :
902 : //------------------------------------------------------------------------------------------------------------------
903 1 : void UnoControlTableModel::notifyRowsRemoved( GridDataEvent const & i_event ) const
904 : {
905 1 : ModellListeners aListeners( m_pImpl->m_aListeners );
906 6 : for ( ModellListeners::const_iterator loop = aListeners.begin();
907 4 : loop != aListeners.end();
908 : ++loop
909 : )
910 : {
911 1 : (*loop)->rowsRemoved( i_event.FirstRow, i_event.LastRow );
912 1 : }
913 1 : }
914 :
915 : //------------------------------------------------------------------------------------------------------------------
916 0 : void UnoControlTableModel::notifyDataChanged( ::com::sun::star::awt::grid::GridDataEvent const & i_event ) const
917 : {
918 0 : ColPos const firstCol = i_event.FirstColumn == -1 ? 0 : i_event.FirstColumn;
919 0 : ColPos const lastCol = i_event.FirstColumn == -1 ? getColumnCount() - 1 : i_event.LastColumn;
920 0 : RowPos const firstRow = i_event.FirstRow == -1 ? 0 : i_event.FirstRow;
921 0 : RowPos const lastRow = i_event.FirstRow == -1 ? getRowCount() - 1 : i_event.LastRow;
922 :
923 0 : ModellListeners aListeners( m_pImpl->m_aListeners );
924 0 : for ( ModellListeners::const_iterator loop = aListeners.begin();
925 0 : loop != aListeners.end();
926 : ++loop
927 : )
928 : {
929 0 : (*loop)->cellsUpdated( firstCol, lastCol, firstRow, lastRow );
930 0 : }
931 0 : }
932 :
933 : //------------------------------------------------------------------------------------------------------------------
934 0 : void UnoControlTableModel::notifyAllDataChanged() const
935 : {
936 0 : ModellListeners aListeners( m_pImpl->m_aListeners );
937 0 : for ( ModellListeners::const_iterator loop = aListeners.begin();
938 0 : loop != aListeners.end();
939 : ++loop
940 : )
941 : {
942 0 : (*loop)->cellsUpdated( 0, getColumnCount() - 1, 0, getRowCount() - 1 );
943 0 : }
944 0 : }
945 :
946 : // .....................................................................................................................
947 465 : } } // svt::table
948 : // .....................................................................................................................
949 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|