1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "gridcontrol.hxx"
22 #include "grideventforwarder.hxx"
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <com/sun/star/view/SelectionType.hpp>
26 #include <com/sun/star/awt/grid/XGridControl.hpp>
27 #include <com/sun/star/awt/grid/XGridDataModel.hpp>
28 #include <com/sun/star/awt/grid/XGridRowSelection.hpp>
29 #include <com/sun/star/awt/grid/XMutableGridDataModel.hpp>
30 #include <com/sun/star/awt/grid/DefaultGridDataModel.hpp>
31 #include <com/sun/star/awt/grid/SortableGridDataModel.hpp>
32 #include <com/sun/star/awt/grid/DefaultGridColumnModel.hpp>
33 #include <helper/property.hxx>
34 #include <comphelper/diagnose_ex.hxx>
35 #include <toolkit/controls/unocontrolbase.hxx>
36 #include <toolkit/controls/unocontrolmodel.hxx>
37 #include <toolkit/helper/listenermultiplexer.hxx>
41 #include <helper/unopropertyarrayhelper.hxx>
43 using namespace ::com::sun::star
;
44 using namespace ::com::sun::star::uno
;
45 using namespace ::com::sun::star::awt
;
46 using namespace ::com::sun::star::awt::grid
;
47 using namespace ::com::sun::star::lang
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::container
;
50 using namespace ::com::sun::star::view
;
51 using namespace ::com::sun::star::util
;
57 Reference
< XGridDataModel
> lcl_getDefaultDataModel_throw( const Reference
<XComponentContext
> & i_context
)
59 Reference
< XMutableGridDataModel
> const xDelegatorModel( DefaultGridDataModel::create( i_context
), UNO_SET_THROW
);
60 Reference
< XGridDataModel
> const xDataModel( SortableGridDataModel::create( i_context
, xDelegatorModel
), UNO_QUERY_THROW
);
64 Reference
< XGridColumnModel
> lcl_getDefaultColumnModel_throw( const Reference
<XComponentContext
> & i_context
)
66 Reference
< XGridColumnModel
> const xColumnModel
= DefaultGridColumnModel::create( i_context
);
72 UnoGridModel::UnoGridModel( const css::uno::Reference
< css::uno::XComponentContext
>& rxContext
)
73 :UnoControlModel( rxContext
)
75 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR
);
76 ImplRegisterProperty( BASEPROPERTY_BORDER
);
77 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR
);
78 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL
);
79 ImplRegisterProperty( BASEPROPERTY_ENABLED
);
80 ImplRegisterProperty( BASEPROPERTY_FILLCOLOR
);
81 ImplRegisterProperty( BASEPROPERTY_HELPTEXT
);
82 ImplRegisterProperty( BASEPROPERTY_HELPURL
);
83 ImplRegisterProperty( BASEPROPERTY_PRINTABLE
);
84 ImplRegisterProperty( BASEPROPERTY_SIZEABLE
); // resizable
85 ImplRegisterProperty( BASEPROPERTY_HSCROLL
);
86 ImplRegisterProperty( BASEPROPERTY_VSCROLL
);
87 ImplRegisterProperty( BASEPROPERTY_TABSTOP
);
88 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER
);
89 ImplRegisterProperty( BASEPROPERTY_ROW_HEADER_WIDTH
);
90 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER
);
91 ImplRegisterProperty( BASEPROPERTY_COLUMN_HEADER_HEIGHT
);
92 ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT
);
93 ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL
, Any( lcl_getDefaultDataModel_throw( m_xContext
) ) );
94 ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL
, Any( lcl_getDefaultColumnModel_throw( m_xContext
) ) );
95 ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE
);
96 ImplRegisterProperty( BASEPROPERTY_FONTRELIEF
);
97 ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK
);
98 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR
);
99 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR
);
100 ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR
);
101 ImplRegisterProperty( BASEPROPERTY_USE_GRID_LINES
);
102 ImplRegisterProperty( BASEPROPERTY_GRID_LINE_COLOR
);
103 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND
);
104 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_TEXT_COLOR
);
105 ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
);
106 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
);
107 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
);
108 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
);
109 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
);
110 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN
);
114 UnoGridModel::UnoGridModel( const UnoGridModel
& rModel
)
115 :UnoControlModel( rModel
)
117 osl_atomic_increment( &m_refCount
);
119 Reference
< XGridDataModel
> xDataModel
;
120 // clone the data model
121 const Reference
< XFastPropertySet
> xCloneSource( &const_cast< UnoGridModel
& >( rModel
) );
124 const Reference
< XCloneable
> xCloneable( xCloneSource
->getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL
), UNO_QUERY_THROW
);
125 xDataModel
.set( xCloneable
->createClone(), UNO_QUERY_THROW
);
127 catch( const Exception
& )
129 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
131 if ( !xDataModel
.is() )
132 xDataModel
= lcl_getDefaultDataModel_throw( m_xContext
);
133 std::unique_lock
aGuard(m_aMutex
);
134 UnoControlModel::setFastPropertyValue_NoBroadcast( aGuard
, BASEPROPERTY_GRID_DATAMODEL
, Any( xDataModel
) );
135 // do *not* use setFastPropertyValue here: The UnoControlModel ctor made a simple copy of all property values,
136 // so before this call here, we share our data model with the own of the clone source. setFastPropertyValue,
137 // then, disposes the old data model - which means the data model which in fact belongs to the clone source.
138 // so, call the UnoControlModel's impl-method for setting the value.
140 // clone the column model
141 Reference
< XGridColumnModel
> xColumnModel
;
144 const Reference
< XCloneable
> xCloneable( xCloneSource
->getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL
), UNO_QUERY_THROW
);
145 xColumnModel
.set( xCloneable
->createClone(), UNO_QUERY_THROW
);
147 catch( const Exception
& )
149 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
151 if ( !xColumnModel
.is() )
152 xColumnModel
= lcl_getDefaultColumnModel_throw( m_xContext
);
153 UnoControlModel::setFastPropertyValue_NoBroadcast( aGuard
, BASEPROPERTY_GRID_COLUMNMODEL
, Any( xColumnModel
) );
154 // same comment as above: do not use our own setPropertyValue here.
156 osl_atomic_decrement( &m_refCount
);
160 rtl::Reference
<UnoControlModel
> UnoGridModel::Clone() const
162 return new UnoGridModel( *this );
168 void lcl_dispose_nothrow( const Any
& i_component
)
172 const Reference
< XComponent
> xComponent( i_component
, UNO_QUERY
);
174 xComponent
->dispose();
176 catch( const Exception
& )
178 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
184 void SAL_CALL
UnoGridModel::dispose( )
186 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL
) );
187 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL
) );
189 UnoControlModel::dispose();
193 void UnoGridModel::setFastPropertyValue_NoBroadcast( std::unique_lock
<std::mutex
>& rGuard
, sal_Int32 nHandle
, const Any
& rValue
)
196 if ( ( nHandle
== BASEPROPERTY_GRID_COLUMNMODEL
) || ( nHandle
== BASEPROPERTY_GRID_DATAMODEL
) )
198 getFastPropertyValue( rGuard
, aOldSubModel
, nHandle
);
199 if ( aOldSubModel
== rValue
)
201 OSL_ENSURE( false, "UnoGridModel::setFastPropertyValue_NoBroadcast: setting the same value, again!" );
202 // shouldn't this have been caught by convertFastPropertyValue?
203 aOldSubModel
.clear();
207 UnoControlModel::setFastPropertyValue_NoBroadcast( rGuard
, nHandle
, rValue
);
209 if ( aOldSubModel
.hasValue() )
210 lcl_dispose_nothrow( aOldSubModel
);
214 OUString
UnoGridModel::getServiceName()
216 return "com.sun.star.awt.grid.UnoControlGridModel";
220 Any
UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId
) const
224 case BASEPROPERTY_DEFAULTCONTROL
:
225 return uno::Any( OUString("com.sun.star.awt.grid.UnoControlGrid") );
226 case BASEPROPERTY_GRID_SELECTIONMODE
:
227 return uno::Any( SelectionType(1) );
228 case BASEPROPERTY_GRID_SHOWROWHEADER
:
229 case BASEPROPERTY_USE_GRID_LINES
:
230 return uno::Any( false );
231 case BASEPROPERTY_ROW_HEADER_WIDTH
:
232 return uno::Any( sal_Int32( 10 ) );
233 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER
:
234 return uno::Any( true );
235 case BASEPROPERTY_COLUMN_HEADER_HEIGHT
:
236 case BASEPROPERTY_ROW_HEIGHT
:
237 case BASEPROPERTY_GRID_HEADER_BACKGROUND
:
238 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR
:
239 case BASEPROPERTY_GRID_LINE_COLOR
:
240 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS
:
241 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR
:
242 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR
:
243 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR
:
244 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR
:
247 return UnoControlModel::ImplGetDefaultValue( nPropId
);
253 ::cppu::IPropertyArrayHelper
& UnoGridModel::getInfoHelper()
255 static UnoPropertyArrayHelper
aHelper( ImplGetPropertyIds() );
261 Reference
< XPropertySetInfo
> UnoGridModel::getPropertySetInfo( )
263 static Reference
< XPropertySetInfo
> xInfo( createPropertySetInfo( getInfoHelper() ) );
270 UnoGridControl::UnoGridControl()
271 :m_aSelectionListeners( *this )
272 ,m_pEventForwarder( new toolkit::GridEventForwarder( *this ) )
277 UnoGridControl::~UnoGridControl()
282 OUString
UnoGridControl::GetComponentServiceName() const
288 void SAL_CALL
UnoGridControl::dispose( )
290 lang::EventObject aEvt
;
291 aEvt
.Source
= getXWeak();
292 m_aSelectionListeners
.disposeAndClear( aEvt
);
293 UnoControl::dispose();
297 void SAL_CALL
UnoGridControl::createPeer( const uno::Reference
< awt::XToolkit
> & rxToolkit
, const uno::Reference
< awt::XWindowPeer
> & rParentPeer
)
299 UnoControlBase::createPeer( rxToolkit
, rParentPeer
);
301 const Reference
< XGridRowSelection
> xGrid( getPeer(), UNO_QUERY_THROW
);
302 xGrid
->addSelectionListener( &m_aSelectionListeners
);
308 void lcl_setEventForwarding( const Reference
< XControlModel
>& i_gridControlModel
, const std::unique_ptr
< toolkit::GridEventForwarder
>& i_listener
,
311 const Reference
< XPropertySet
> xModelProps( i_gridControlModel
, UNO_QUERY
);
312 if ( !xModelProps
.is() )
317 Reference
< XContainer
> const xColModel(
318 xModelProps
->getPropertyValue("ColumnModel"),
321 xColModel
->addContainerListener( i_listener
.get() );
323 xColModel
->removeContainerListener( i_listener
.get() );
325 Reference
< XGridDataModel
> const xDataModel(
326 xModelProps
->getPropertyValue("GridDataModel"),
329 Reference
< XMutableGridDataModel
> const xMutableDataModel( xDataModel
, UNO_QUERY
);
330 if ( xMutableDataModel
.is() )
333 xMutableDataModel
->addGridDataListener( i_listener
.get() );
335 xMutableDataModel
->removeGridDataListener( i_listener
.get() );
338 catch( const Exception
& )
340 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
346 sal_Bool SAL_CALL
UnoGridControl::setModel( const Reference
< XControlModel
>& i_model
)
348 lcl_setEventForwarding( getModel(), m_pEventForwarder
, false );
349 if ( !UnoGridControl_Base::setModel( i_model
) )
351 lcl_setEventForwarding( getModel(), m_pEventForwarder
, true );
356 ::sal_Int32
UnoGridControl::getRowAtPoint(::sal_Int32 x
, ::sal_Int32 y
)
358 Reference
< XGridControl
> const xGrid ( getPeer(), UNO_QUERY_THROW
);
359 return xGrid
->getRowAtPoint( x
, y
);
363 ::sal_Int32
UnoGridControl::getColumnAtPoint(::sal_Int32 x
, ::sal_Int32 y
)
365 Reference
< XGridControl
> const xGrid ( getPeer(), UNO_QUERY_THROW
);
366 return xGrid
->getColumnAtPoint( x
, y
);
370 ::sal_Int32 SAL_CALL
UnoGridControl::getCurrentColumn( )
372 Reference
< XGridControl
> const xGrid ( getPeer(), UNO_QUERY_THROW
);
373 return xGrid
->getCurrentColumn();
377 ::sal_Int32 SAL_CALL
UnoGridControl::getCurrentRow( )
379 Reference
< XGridControl
> const xGrid ( getPeer(), UNO_QUERY_THROW
);
380 return xGrid
->getCurrentRow();
384 void SAL_CALL
UnoGridControl::goToCell( ::sal_Int32 i_columnIndex
, ::sal_Int32 i_rowIndex
)
386 Reference
< XGridControl
> const xGrid ( getPeer(), UNO_QUERY_THROW
);
387 xGrid
->goToCell( i_columnIndex
, i_rowIndex
);
391 void SAL_CALL
UnoGridControl::selectRow( ::sal_Int32 i_rowIndex
)
393 Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->selectRow( i_rowIndex
);
397 void SAL_CALL
UnoGridControl::selectAllRows()
399 Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->selectAllRows();
403 void SAL_CALL
UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex
)
405 Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->deselectRow( i_rowIndex
);
409 void SAL_CALL
UnoGridControl::deselectAllRows()
411 Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->deselectAllRows();
415 css::uno::Sequence
< ::sal_Int32
> SAL_CALL
UnoGridControl::getSelectedRows()
417 return Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->getSelectedRows();
421 sal_Bool SAL_CALL
UnoGridControl::hasSelectedRows()
423 return Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->hasSelectedRows();
427 sal_Bool SAL_CALL
UnoGridControl::isRowSelected(::sal_Int32 index
)
429 return Reference
< XGridRowSelection
>( getPeer(), UNO_QUERY_THROW
)->isRowSelected( index
);
433 void SAL_CALL
UnoGridControl::addSelectionListener(const css::uno::Reference
< css::awt::grid::XGridSelectionListener
> & listener
)
435 m_aSelectionListeners
.addInterface( listener
);
439 void SAL_CALL
UnoGridControl::removeSelectionListener(const css::uno::Reference
< css::awt::grid::XGridSelectionListener
> & listener
)
441 m_aSelectionListeners
.removeInterface( listener
);
446 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
447 stardiv_Toolkit_GridControl_get_implementation(
448 css::uno::XComponentContext
*,
449 css::uno::Sequence
<css::uno::Any
> const &)
451 return cppu::acquire(new toolkit::UnoGridControl());
454 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
455 stardiv_Toolkit_GridControlModel_get_implementation(
456 css::uno::XComponentContext
*context
,
457 css::uno::Sequence
<css::uno::Any
> const &)
459 return cppu::acquire(new toolkit::UnoGridModel(context
));
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */