1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_toolkit.hxx" 26 27 #include "gridcontrol.hxx" 28 #include "grideventforwarder.hxx" 29 30 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 31 #include <com/sun/star/view/SelectionType.hpp> 32 #include <com/sun/star/awt/grid/XGridDataModel.hpp> 33 #include <com/sun/star/awt/grid/XMutableGridDataModel.hpp> 34 #include <com/sun/star/awt/grid/DefaultGridDataModel.hpp> 35 #include <com/sun/star/awt/grid/SortableGridDataModel.hpp> 36 #include <com/sun/star/awt/grid/XGridColumnModel.hpp> 37 #include <toolkit/helper/unopropertyarrayhelper.hxx> 38 #include <toolkit/helper/property.hxx> 39 #include <com/sun/star/awt/XVclWindowPeer.hpp> 40 #include <comphelper/processfactory.hxx> 41 #include <tools/diagnose_ex.h> 42 #include <tools/color.hxx> 43 44 using ::rtl::OUString; 45 using namespace ::com::sun::star; 46 using namespace ::com::sun::star::uno; 47 using namespace ::com::sun::star::awt; 48 using namespace ::com::sun::star::awt::grid; 49 using namespace ::com::sun::star::lang; 50 using namespace ::com::sun::star::beans; 51 using namespace ::com::sun::star::container; 52 using namespace ::com::sun::star::view; 53 using namespace ::com::sun::star::util; 54 55 namespace toolkit 56 { 57 //====================================================================================================================== 58 //= UnoGridModel 59 //====================================================================================================================== 60 namespace 61 { 62 Reference< XGridDataModel > lcl_getDefaultDataModel_throw( ::comphelper::ComponentContext const & i_context ) 63 { 64 Reference< XMutableGridDataModel > const xDelegatorModel( DefaultGridDataModel::create( i_context.getUNOContext() ), UNO_QUERY_THROW ); 65 Reference< XGridDataModel > const xDataModel( SortableGridDataModel::create( i_context.getUNOContext(), xDelegatorModel ), UNO_QUERY_THROW ); 66 return xDataModel; 67 } 68 69 Reference< XGridColumnModel > lcl_getDefaultColumnModel_throw( ::comphelper::ComponentContext const & i_context ) 70 { 71 Reference< XGridColumnModel > const xColumnModel( i_context.createComponent( "com.sun.star.awt.grid.DefaultGridColumnModel" ), UNO_QUERY_THROW ); 72 return xColumnModel; 73 } 74 } 75 76 //---------------------------------------------------------------------------------------------------------------------- 77 UnoGridModel::UnoGridModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) 78 :UnoControlModel( i_factory ) 79 { 80 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); 81 ImplRegisterProperty( BASEPROPERTY_BORDER ); 82 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); 83 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); 84 ImplRegisterProperty( BASEPROPERTY_ENABLED ); 85 ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); 86 ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); 87 ImplRegisterProperty( BASEPROPERTY_HELPURL ); 88 ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); 89 ImplRegisterProperty( BASEPROPERTY_SIZEABLE ); // resizeable 90 ImplRegisterProperty( BASEPROPERTY_HSCROLL ); 91 ImplRegisterProperty( BASEPROPERTY_VSCROLL ); 92 ImplRegisterProperty( BASEPROPERTY_TABSTOP ); 93 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWROWHEADER ); 94 ImplRegisterProperty( BASEPROPERTY_ROW_HEADER_WIDTH ); 95 ImplRegisterProperty( BASEPROPERTY_GRID_SHOWCOLUMNHEADER ); 96 ImplRegisterProperty( BASEPROPERTY_COLUMN_HEADER_HEIGHT ); 97 ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT ); 98 ImplRegisterProperty( BASEPROPERTY_GRID_DATAMODEL, makeAny( lcl_getDefaultDataModel_throw( maContext ) ) ); 99 ImplRegisterProperty( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( lcl_getDefaultColumnModel_throw( maContext ) ) ); 100 ImplRegisterProperty( BASEPROPERTY_GRID_SELECTIONMODE ); 101 ImplRegisterProperty( BASEPROPERTY_FONTRELIEF ); 102 ImplRegisterProperty( BASEPROPERTY_FONTEMPHASISMARK ); 103 ImplRegisterProperty( BASEPROPERTY_FONTDESCRIPTOR ); 104 ImplRegisterProperty( BASEPROPERTY_TEXTCOLOR ); 105 ImplRegisterProperty( BASEPROPERTY_TEXTLINECOLOR ); 106 ImplRegisterProperty( BASEPROPERTY_USE_GRID_LINES ); 107 ImplRegisterProperty( BASEPROPERTY_GRID_LINE_COLOR ); 108 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_BACKGROUND ); 109 ImplRegisterProperty( BASEPROPERTY_GRID_HEADER_TEXT_COLOR ); 110 ImplRegisterProperty( BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS ); 111 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR ); 112 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR ); 113 ImplRegisterProperty( BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR ); 114 ImplRegisterProperty( BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR ); 115 ImplRegisterProperty( BASEPROPERTY_VERTICALALIGN ); 116 } 117 118 //---------------------------------------------------------------------------------------------------------------------- 119 UnoGridModel::UnoGridModel( const UnoGridModel& rModel ) 120 :UnoControlModel( rModel ) 121 { 122 osl_incrementInterlockedCount( &m_refCount ); 123 { 124 Reference< XGridDataModel > xDataModel; 125 // clone the data model 126 const Reference< XFastPropertySet > xCloneSource( &const_cast< UnoGridModel& >( rModel ) ); 127 try 128 { 129 const Reference< XCloneable > xCloneable( xCloneSource->getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ), UNO_QUERY_THROW ); 130 xDataModel.set( xCloneable->createClone(), UNO_QUERY_THROW ); 131 } 132 catch( const Exception& ) 133 { 134 DBG_UNHANDLED_EXCEPTION(); 135 } 136 if ( !xDataModel.is() ) 137 xDataModel = lcl_getDefaultDataModel_throw( maContext ); 138 UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_DATAMODEL, makeAny( xDataModel ) ); 139 // do *not* use setFastPropertyValue here: The UnoControlModel ctor did a simple copy of all property values, 140 // so before this call here, we share our data model with the own of the clone source. setFastPropertyValue, 141 // then, disposes the old data model - which means the data model which in fact belongs to the clone source. 142 // so, call the UnoControlModel's impl-method for setting the value. 143 144 // clone the column model 145 Reference< XGridColumnModel > xColumnModel; 146 try 147 { 148 const Reference< XCloneable > xCloneable( xCloneSource->getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL ), UNO_QUERY_THROW ); 149 xColumnModel.set( xCloneable->createClone(), UNO_QUERY_THROW ); 150 } 151 catch( const Exception& ) 152 { 153 DBG_UNHANDLED_EXCEPTION(); 154 } 155 if ( !xColumnModel.is() ) 156 xColumnModel = lcl_getDefaultColumnModel_throw( maContext ); 157 UnoControlModel::setFastPropertyValue_NoBroadcast( BASEPROPERTY_GRID_COLUMNMODEL, makeAny( xColumnModel ) ); 158 // same comment as above: do not use our own setPropertyValue here. 159 } 160 osl_decrementInterlockedCount( &m_refCount ); 161 } 162 163 //---------------------------------------------------------------------------------------------------------------------- 164 UnoControlModel* UnoGridModel::Clone() const 165 { 166 return new UnoGridModel( *this ); 167 } 168 169 //---------------------------------------------------------------------------------------------------------------------- 170 namespace 171 { 172 void lcl_dispose_nothrow( const Any& i_component ) 173 { 174 try 175 { 176 const Reference< XComponent > xComponent( i_component, UNO_QUERY_THROW ); 177 xComponent->dispose(); 178 } 179 catch( const Exception& ) 180 { 181 DBG_UNHANDLED_EXCEPTION(); 182 } 183 } 184 } 185 186 //---------------------------------------------------------------------------------------------------------------------- 187 void SAL_CALL UnoGridModel::dispose( ) throw(RuntimeException) 188 { 189 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_COLUMNMODEL ) ); 190 lcl_dispose_nothrow( getFastPropertyValue( BASEPROPERTY_GRID_DATAMODEL ) ); 191 192 UnoControlModel::dispose(); 193 } 194 195 //---------------------------------------------------------------------------------------------------------------------- 196 void SAL_CALL UnoGridModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) 197 { 198 Any aOldSubModel; 199 if ( ( nHandle == BASEPROPERTY_GRID_COLUMNMODEL ) || ( nHandle == BASEPROPERTY_GRID_DATAMODEL ) ) 200 { 201 aOldSubModel = getFastPropertyValue( nHandle ); 202 if ( aOldSubModel == rValue ) 203 { 204 OSL_ENSURE( false, "UnoGridModel::setFastPropertyValue_NoBroadcast: setting the same value, again!" ); 205 // shouldn't this have been caught by convertFastPropertyValue? 206 aOldSubModel.clear(); 207 } 208 } 209 210 UnoControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); 211 212 if ( aOldSubModel.hasValue() ) 213 lcl_dispose_nothrow( aOldSubModel ); 214 } 215 216 //---------------------------------------------------------------------------------------------------------------------- 217 OUString UnoGridModel::getServiceName() throw(RuntimeException) 218 { 219 return OUString::createFromAscii( szServiceName_GridControlModel ); 220 } 221 222 //---------------------------------------------------------------------------------------------------------------------- 223 Any UnoGridModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const 224 { 225 switch( nPropId ) 226 { 227 case BASEPROPERTY_DEFAULTCONTROL: 228 return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_GridControl ) ); 229 case BASEPROPERTY_GRID_SELECTIONMODE: 230 return uno::makeAny( SelectionType(1) ); 231 case BASEPROPERTY_GRID_SHOWROWHEADER: 232 case BASEPROPERTY_USE_GRID_LINES: 233 return uno::makeAny( (sal_Bool)sal_False ); 234 case BASEPROPERTY_ROW_HEADER_WIDTH: 235 return uno::makeAny( sal_Int32( 10 ) ); 236 case BASEPROPERTY_GRID_SHOWCOLUMNHEADER: 237 return uno::makeAny( (sal_Bool)sal_True ); 238 case BASEPROPERTY_COLUMN_HEADER_HEIGHT: 239 case BASEPROPERTY_ROW_HEIGHT: 240 case BASEPROPERTY_GRID_HEADER_BACKGROUND: 241 case BASEPROPERTY_GRID_HEADER_TEXT_COLOR: 242 case BASEPROPERTY_GRID_LINE_COLOR: 243 case BASEPROPERTY_GRID_ROW_BACKGROUND_COLORS: 244 case BASEPROPERTY_ACTIVE_SEL_BACKGROUND_COLOR: 245 case BASEPROPERTY_INACTIVE_SEL_BACKGROUND_COLOR: 246 case BASEPROPERTY_ACTIVE_SEL_TEXT_COLOR: 247 case BASEPROPERTY_INACTIVE_SEL_TEXT_COLOR: 248 return Any(); 249 default: 250 return UnoControlModel::ImplGetDefaultValue( nPropId ); 251 } 252 253 } 254 255 //---------------------------------------------------------------------------------------------------------------------- 256 ::cppu::IPropertyArrayHelper& UnoGridModel::getInfoHelper() 257 { 258 static UnoPropertyArrayHelper* pHelper = NULL; 259 if ( !pHelper ) 260 { 261 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 262 pHelper = new UnoPropertyArrayHelper( aIDs ); 263 } 264 return *pHelper; 265 } 266 267 //---------------------------------------------------------------------------------------------------------------------- 268 // XMultiPropertySet 269 Reference< XPropertySetInfo > UnoGridModel::getPropertySetInfo( ) throw(RuntimeException) 270 { 271 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 272 return xInfo; 273 } 274 275 276 //====================================================================================================================== 277 //= UnoGridControl 278 //====================================================================================================================== 279 UnoGridControl::UnoGridControl( const Reference< XMultiServiceFactory >& i_factory ) 280 :UnoGridControl_Base( i_factory ) 281 ,mSelectionMode(SelectionType(1)) 282 ,m_aSelectionListeners( *this ) 283 ,m_pEventForwarder( new GridEventForwarder( *this ) ) 284 { 285 } 286 287 //---------------------------------------------------------------------------------------------------------------------- 288 UnoGridControl::~UnoGridControl() 289 { 290 } 291 292 //---------------------------------------------------------------------------------------------------------------------- 293 OUString UnoGridControl::GetComponentServiceName() 294 { 295 return OUString::createFromAscii( "Grid" ); 296 } 297 298 //---------------------------------------------------------------------------------------------------------------------- 299 void SAL_CALL UnoGridControl::dispose( ) throw(RuntimeException) 300 { 301 lang::EventObject aEvt; 302 aEvt.Source = (::cppu::OWeakObject*)this; 303 m_aSelectionListeners.disposeAndClear( aEvt ); 304 UnoControl::dispose(); 305 } 306 307 //---------------------------------------------------------------------------------------------------------------------- 308 void SAL_CALL UnoGridControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) 309 { 310 UnoControlBase::createPeer( rxToolkit, rParentPeer ); 311 312 const Reference< XGridRowSelection > xGrid( getPeer(), UNO_QUERY_THROW ); 313 xGrid->addSelectionListener( &m_aSelectionListeners ); 314 } 315 316 //---------------------------------------------------------------------------------------------------------------------- 317 namespace 318 { 319 void lcl_setEventForwarding( const Reference< XControlModel >& i_gridControlModel, const ::boost::scoped_ptr< GridEventForwarder >& i_listener, 320 bool const i_add ) 321 { 322 const Reference< XPropertySet > xModelProps( i_gridControlModel, UNO_QUERY ); 323 if ( !xModelProps.is() ) 324 return; 325 326 try 327 { 328 Reference< XContainer > const xColModel( 329 xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ColumnModel" ) ) ), 330 UNO_QUERY_THROW ); 331 if ( i_add ) 332 xColModel->addContainerListener( i_listener.get() ); 333 else 334 xColModel->removeContainerListener( i_listener.get() ); 335 336 Reference< XGridDataModel > const xDataModel( 337 xModelProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "GridDataModel" ) ) ), 338 UNO_QUERY_THROW 339 ); 340 Reference< XMutableGridDataModel > const xMutableDataModel( xDataModel, UNO_QUERY ); 341 if ( xMutableDataModel.is() ) 342 { 343 if ( i_add ) 344 xMutableDataModel->addGridDataListener( i_listener.get() ); 345 else 346 xMutableDataModel->removeGridDataListener( i_listener.get() ); 347 } 348 } 349 catch( const Exception& ) 350 { 351 DBG_UNHANDLED_EXCEPTION(); 352 } 353 } 354 } 355 356 //---------------------------------------------------------------------------------------------------------------------- 357 sal_Bool SAL_CALL UnoGridControl::setModel( const Reference< XControlModel >& i_model ) throw(RuntimeException) 358 { 359 lcl_setEventForwarding( getModel(), m_pEventForwarder, false ); 360 if ( !UnoGridControl_Base::setModel( i_model ) ) 361 return sal_False; 362 lcl_setEventForwarding( getModel(), m_pEventForwarder, true ); 363 return sal_True; 364 } 365 366 //---------------------------------------------------------------------------------------------------------------------- 367 ::sal_Int32 UnoGridControl::getRowAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) 368 { 369 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW ); 370 return xGrid->getRowAtPoint( x, y ); 371 } 372 373 //---------------------------------------------------------------------------------------------------------------------- 374 ::sal_Int32 UnoGridControl::getColumnAtPoint(::sal_Int32 x, ::sal_Int32 y) throw (::com::sun::star::uno::RuntimeException) 375 { 376 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW ); 377 return xGrid->getColumnAtPoint( x, y ); 378 } 379 380 //---------------------------------------------------------------------------------------------------------------------- 381 ::sal_Int32 SAL_CALL UnoGridControl::getCurrentColumn( ) throw (RuntimeException) 382 { 383 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW ); 384 return xGrid->getCurrentColumn(); 385 } 386 387 //---------------------------------------------------------------------------------------------------------------------- 388 ::sal_Int32 SAL_CALL UnoGridControl::getCurrentRow( ) throw (RuntimeException) 389 { 390 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW ); 391 return xGrid->getCurrentRow(); 392 } 393 394 //---------------------------------------------------------------------------------------------------------------------- 395 void SAL_CALL UnoGridControl::goToCell( ::sal_Int32 i_columnIndex, ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException, VetoException) 396 { 397 Reference< XGridControl > const xGrid ( getPeer(), UNO_QUERY_THROW ); 398 xGrid->goToCell( i_columnIndex, i_rowIndex ); 399 } 400 401 //---------------------------------------------------------------------------------------------------------------------- 402 void SAL_CALL UnoGridControl::selectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) 403 { 404 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectRow( i_rowIndex ); 405 } 406 407 //---------------------------------------------------------------------------------------------------------------------- 408 void SAL_CALL UnoGridControl::selectAllRows() throw (::com::sun::star::uno::RuntimeException) 409 { 410 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->selectAllRows(); 411 } 412 413 //---------------------------------------------------------------------------------------------------------------------- 414 void SAL_CALL UnoGridControl::deselectRow( ::sal_Int32 i_rowIndex ) throw (RuntimeException, IndexOutOfBoundsException ) 415 { 416 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectRow( i_rowIndex ); 417 } 418 419 //---------------------------------------------------------------------------------------------------------------------- 420 void SAL_CALL UnoGridControl::deselectAllRows() throw (::com::sun::star::uno::RuntimeException) 421 { 422 Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->deselectAllRows(); 423 } 424 425 //---------------------------------------------------------------------------------------------------------------------- 426 ::com::sun::star::uno::Sequence< ::sal_Int32 > SAL_CALL UnoGridControl::getSelectedRows() throw (::com::sun::star::uno::RuntimeException) 427 { 428 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->getSelectedRows(); 429 } 430 431 //---------------------------------------------------------------------------------------------------------------------- 432 ::sal_Bool SAL_CALL UnoGridControl::hasSelectedRows() throw (::com::sun::star::uno::RuntimeException) 433 { 434 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->hasSelectedRows(); 435 } 436 437 //---------------------------------------------------------------------------------------------------------------------- 438 ::sal_Bool SAL_CALL UnoGridControl::isRowSelected(::sal_Int32 index) throw (::com::sun::star::uno::RuntimeException) 439 { 440 return Reference< XGridRowSelection >( getPeer(), UNO_QUERY_THROW )->isRowSelected( index ); 441 } 442 443 //---------------------------------------------------------------------------------------------------------------------- 444 void SAL_CALL UnoGridControl::addSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) 445 { 446 m_aSelectionListeners.addInterface( listener ); 447 } 448 449 //---------------------------------------------------------------------------------------------------------------------- 450 void SAL_CALL UnoGridControl::removeSelectionListener(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::grid::XGridSelectionListener > & listener) throw (::com::sun::star::uno::RuntimeException) 451 { 452 m_aSelectionListeners.removeInterface( listener ); 453 } 454 455 }//namespace toolkit 456 457 Reference< XInterface > SAL_CALL GridControl_CreateInstance( const Reference< XMultiServiceFactory >& i_factory ) 458 { 459 return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridControl( i_factory ) ); 460 } 461 462 Reference< XInterface > SAL_CALL GridControlModel_CreateInstance( const Reference< XMultiServiceFactory >& i_factory ) 463 { 464 return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoGridModel( i_factory ) ); 465 } 466