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