Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / toolkit / source / controls / grid / gridcontrol.cxx
blob3807e570b89e4ce65f21b2c96a0b3971aa09edfd
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <toolkit/helper/property.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <tools/color.hxx>
36 #include <toolkit/controls/unocontrolbase.hxx>
37 #include <toolkit/controls/unocontrolmodel.hxx>
38 #include <toolkit/helper/listenermultiplexer.hxx>
40 #include <memory>
42 #include <helper/unopropertyarrayhelper.hxx>
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::awt;
47 using namespace ::com::sun::star::awt::grid;
48 using namespace ::com::sun::star::lang;
49 using namespace ::com::sun::star::beans;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::view;
52 using namespace ::com::sun::star::util;
54 namespace toolkit {
56 namespace
58 Reference< XGridDataModel > lcl_getDefaultDataModel_throw( const Reference<XComponentContext> & i_context )
60 Reference< XMutableGridDataModel > const xDelegatorModel( DefaultGridDataModel::create( i_context ), UNO_QUERY_THROW );
61 Reference< XGridDataModel > const xDataModel( SortableGridDataModel::create( i_context, xDelegatorModel ), UNO_QUERY_THROW );
62 return xDataModel;
65 Reference< XGridColumnModel > lcl_getDefaultColumnModel_throw( const Reference<XComponentContext> & i_context )
67 Reference< XGridColumnModel > const xColumnModel = DefaultGridColumnModel::create( i_context );
68 return xColumnModel;
73 UnoGridModel::UnoGridModel( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
74 :UnoControlModel( rxContext )
76 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
77 ImplRegisterProperty( BASEPROPERTY_BORDER );
78 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
79 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
80 ImplRegisterProperty( BASEPROPERTY_ENABLED );
81 ImplRegisterProperty( BASEPROPERTY_FILLCOLOR );
82 ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
83 ImplRegisterProperty( BASEPROPERTY_HELPURL );
84 ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
85 ImplRegisterProperty( BASEPROPERTY_SIZEABLE ); // resizable
86 ImplRegisterProperty( BASEPROPERTY_HSCROLL );
87 ImplRegisterProperty( BASEPROPERTY_VSCROLL );
88 ImplRegisterProperty( BASEPROPERTY_TABSTOP );
89 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER );
90 ImplRegisterProperty( BASEPROPERTY_ROW_HEADER_WIDTH );
91 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER );
92 ImplRegisterProperty( BASEPROPERTY_COLUMN_HEADER_HEIGHT );
93 ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT );
94 ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL, makeAny( lcl_getDefaultDataModel_throw( m_xContext ) ) );
95 ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( lcl_getDefaultColumnModel_throw( m_xContext ) ) );
96 ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE );
97 ImplRegisterProperty( BASEPROPERTY_FONTRELIEF );
98 ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK );
99 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR );
100 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR );
101 ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR );
102 ImplRegisterProperty( BASEPROPERTY_USE_GRID_LINES );
103 ImplRegisterProperty( BASEPROPERTY_GRID_LINE_COLOR );
104 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND );
105 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_TEXT_COLOR );
106 ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS );
107 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR );
108 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR );
109 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR );
110 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR );
111 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN );
115 UnoGridModel::UnoGridModel( const UnoGridModel& rModel )
116 :UnoControlModel( rModel )
118 osl_atomic_increment( &m_refCount );
120 Reference< XGridDataModel > xDataModel;
121 // clone the data model
122 const Reference< XFastPropertySet > xCloneSource( &const_cast< UnoGridModel& >( rModel ) );
125 const Reference< XCloneable > xCloneable( xCloneSource->getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ), UNO_QUERY_THROW );
126 xDataModel.set( xCloneable->createClone(), UNO_QUERY_THROW );
128 catch( const Exception& )
130 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
132 if ( !xDataModel.is() )
133 xDataModel = lcl_getDefaultDataModel_throw( m_xContext );
134 UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_DATAMODEL, makeAny( xDataModel ) );
135 // do *not* use setFastPropertyValue here: The UnoControlModel ctor did 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( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( 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 );
166 namespace
168 void lcl_dispose_nothrow( const Any& i_component )
172 const Reference< XComponent > xComponent( i_component, UNO_QUERY_THROW );
173 xComponent->dispose();
175 catch( const Exception& )
177 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
183 void SAL_CALL UnoGridModel::dispose( )
185 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL ) );
186 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ) );
188 UnoControlModel::dispose();
192 void SAL_CALL UnoGridModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue )
194 Any aOldSubModel;
195 if ( ( nHandle == BASEPROPERTY_GRID_COLUMNMODEL ) || ( nHandle == BASEPROPERTY_GRID_DATAMODEL ) )
197 aOldSubModel = getFastPropertyValue( nHandle );
198 if ( aOldSubModel == rValue )
200 OSL_ENSURE( false, "UnoGridModel::setFastPropertyValue_NoBroadcast: setting the same value, again!" );
201 // shouldn't this have been caught by convertFastPropertyValue?
202 aOldSubModel.clear();
206 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
208 if ( aOldSubModel.hasValue() )
209 lcl_dispose_nothrow( aOldSubModel );
213 OUString UnoGridModel::getServiceName()
215 return OUString("com.sun.star.awt.grid.UnoControlGridModel");
219 Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
221 switch( nPropId )
223 case BASEPROPERTY_DEFAULTCONTROL:
224 return uno::makeAny( OUString("com.sun.star.awt.grid.UnoControlGrid") );
225 case BASEPROPERTY_GRID_SELECTIONMODE:
226 return uno::makeAny( SelectionType(1) );
227 case BASEPROPERTY_GRID_SHOWROWHEADER:
228 case BASEPROPERTY_USE_GRID_LINES:
229 return uno::makeAny( false );
230 case BASEPROPERTY_ROW_HEADER_WIDTH:
231 return uno::makeAny( sal_Int32( 10 ) );
232 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER:
233 return uno::makeAny( true );
234 case BASEPROPERTY_COLUMN_HEADER_HEIGHT:
235 case BASEPROPERTY_ROW_HEIGHT:
236 case BASEPROPERTY_GRID_HEADER_BACKGROUND:
237 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR:
238 case BASEPROPERTY_GRID_LINE_COLOR:
239 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS:
240 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR:
241 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR:
242 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR:
243 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR:
244 return Any();
245 default:
246 return UnoControlModel::ImplGetDefaultValue( nPropId );
252 ::cppu::IPropertyArrayHelper& UnoGridModel::getInfoHelper()
254 static UnoPropertyArrayHelper* pHelper = nullptr;
255 if ( !pHelper )
257 Sequence<sal_Int32> aIDs = ImplGetPropertyIds();
258 pHelper = new UnoPropertyArrayHelper( aIDs );
260 return *pHelper;
264 // XMultiPropertySet
265 Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( )
267 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
268 return xInfo;
272 //= UnoGridControl
274 UnoGridControl::UnoGridControl()
275 :UnoGridControl_Base()
276 ,m_aSelectionListeners( *this )
277 ,m_pEventForwarder( new toolkit::GridEventForwarder( *this ) )
282 UnoGridControl::~UnoGridControl()
287 OUString UnoGridControl::GetComponentServiceName()
289 return OUString("Grid");
293 void SAL_CALL UnoGridControl::dispose( )
295 lang::EventObject aEvt;
296 aEvt.Source = static_cast<cppu::OWeakObject*>(this);
297 m_aSelectionListeners.disposeAndClear( aEvt );
298 UnoControl::dispose();
302 void SAL_CALL UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer )
304 UnoControlBase::createPeer( rxToolkit, rParentPeer );
306 const Reference< XGridRowSelection > xGrid( getPeer(), UNO_QUERY_THROW );
307 xGrid->addSelectionListener( &m_aSelectionListeners );
311 namespace
313 void lcl_setEventForwarding( const Reference< XControlModel >& i_gridControlModel, const std::unique_ptr< toolkit::GridEventForwarder >& i_listener,
314 bool const i_add )
316 const Reference< XPropertySet > xModelProps( i_gridControlModel, UNO_QUERY );
317 if ( !xModelProps.is() )
318 return;
322 Reference< XContainer > const xColModel(
323 xModelProps->getPropertyValue("ColumnModel"),
324 UNO_QUERY_THROW );
325 if ( i_add )
326 xColModel->addContainerListener( i_listener.get() );
327 else
328 xColModel->removeContainerListener( i_listener.get() );
330 Reference< XGridDataModel > const xDataModel(
331 xModelProps->getPropertyValue("GridDataModel"),
332 UNO_QUERY_THROW
334 Reference< XMutableGridDataModel > const xMutableDataModel( xDataModel, UNO_QUERY );
335 if ( xMutableDataModel.is() )
337 if ( i_add )
338 xMutableDataModel->addGridDataListener( i_listener.get() );
339 else
340 xMutableDataModel->removeGridDataListener( i_listener.get() );
343 catch( const Exception& )
345 DBG_UNHANDLED_EXCEPTION("toolkit.controls");
351 sal_Bool SAL_CALL UnoGridControl::setModel( const Reference< XControlModel >& i_model )
353 lcl_setEventForwarding( getModel(), m_pEventForwarder, false );
354 if ( !UnoGridControl_Base::setModel( i_model ) )
355 return false;
356 lcl_setEventForwarding( getModel(), m_pEventForwarder, true );
357 return true;
361 ::sal_Int32 UnoGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y)
363 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
364 return xGrid->getRowAtPoint( x, y );
368 ::sal_Int32 UnoGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y)
370 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
371 return xGrid->getColumnAtPoint( x, y );
375 ::sal_Int32 SAL_CALL UnoGridControl::getCurrentColumn( )
377 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
378 return xGrid->getCurrentColumn();
382 ::sal_Int32 SAL_CALL UnoGridControl::getCurrentRow( )
384 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
385 return xGrid->getCurrentRow();
389 void SAL_CALL UnoGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex )
391 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW );
392 xGrid->goToCell( i_columnIndex, i_rowIndex );
396 void SAL_CALL UnoGridControl::selectRow( ::sal_Int32 i_rowIndex )
398 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectRow( i_rowIndex );
402 void SAL_CALL UnoGridControl::selectAllRows()
404 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectAllRows();
408 void SAL_CALL UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex )
410 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectRow( i_rowIndex );
414 void SAL_CALL UnoGridControl::deselectAllRows()
416 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectAllRows();
420 css::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelectedRows()
422 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->getSelectedRows();
426 sal_Bool SAL_CALL UnoGridControl::hasSelectedRows()
428 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->hasSelectedRows();
432 sal_Bool SAL_CALL UnoGridControl::isRowSelected(::sal_Int32 index)
434 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->isRowSelected( index );
438 void SAL_CALL UnoGridControl::addSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > & listener)
440 m_aSelectionListeners.addInterface( listener );
444 void SAL_CALL UnoGridControl::removeSelectionListener(const css::uno::Reference< css::awt::grid::XGridSelectionListener > & listener)
446 m_aSelectionListeners.removeInterface( listener );
451 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
452 stardiv_Toolkit_GridControl_get_implementation(
453 css::uno::XComponentContext *,
454 css::uno::Sequence<css::uno::Any> const &)
456 return cppu::acquire(new toolkit::UnoGridControl());
459 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
460 stardiv_Toolkit_GridControlModel_get_implementation(
461 css::uno::XComponentContext *context,
462 css::uno::Sequence<css::uno::Any> const &)
464 return cppu::acquire(new toolkit::UnoGridModel(context));
467 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */