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