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