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 #ifndef _TOOLKIT_TREE_CONTROL_HXX 28 #include <treecontrol.hxx> 29 #endif 30 31 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 32 #include <com/sun/star/view/SelectionType.hpp> 33 #include <com/sun/star/awt/tree/XTreeDataModel.hpp> 34 #include <toolkit/helper/unopropertyarrayhelper.hxx> 35 #include <toolkit/helper/property.hxx> 36 #include <com/sun/star/awt/XVclWindowPeer.hpp> 37 #include <comphelper/processfactory.hxx> 38 #include <osl/diagnose.h> 39 40 using ::rtl::OUString; 41 using namespace ::com::sun::star; 42 using namespace ::com::sun::star::uno; 43 using namespace ::com::sun::star::awt::tree; 44 using namespace ::com::sun::star::lang; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star::container; 47 using namespace ::com::sun::star::view; 48 49 namespace toolkit 50 { 51 // ---------------------------------------------------- 52 // class UnoTreeModel 53 // ---------------------------------------------------- 54 UnoTreeModel::UnoTreeModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory ) 55 :UnoControlModel( i_factory ) 56 { 57 ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR ); 58 ImplRegisterProperty( BASEPROPERTY_BORDER ); 59 ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR ); 60 ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL ); 61 ImplRegisterProperty( BASEPROPERTY_ENABLED ); 62 ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE ); 63 ImplRegisterProperty( BASEPROPERTY_FILLCOLOR ); 64 ImplRegisterProperty( BASEPROPERTY_HELPTEXT ); 65 ImplRegisterProperty( BASEPROPERTY_HELPURL ); 66 ImplRegisterProperty( BASEPROPERTY_PRINTABLE ); 67 ImplRegisterProperty( BASEPROPERTY_TABSTOP ); 68 ImplRegisterProperty( BASEPROPERTY_TREE_SELECTIONTYPE ); 69 ImplRegisterProperty( BASEPROPERTY_TREE_EDITABLE ); 70 ImplRegisterProperty( BASEPROPERTY_TREE_DATAMODEL ); 71 ImplRegisterProperty( BASEPROPERTY_TREE_ROOTDISPLAYED ); 72 ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSHANDLES ); 73 ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSROOTHANDLES ); 74 ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT ); 75 ImplRegisterProperty( BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING ); 76 ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION ); 77 } 78 79 UnoTreeModel::UnoTreeModel( const UnoTreeModel& rModel ) 80 : UnoControlModel( rModel ) 81 { 82 } 83 84 UnoControlModel* UnoTreeModel::Clone() const 85 { 86 return new UnoTreeModel( *this ); 87 } 88 89 OUString UnoTreeModel::getServiceName() throw(RuntimeException) 90 { 91 return OUString::createFromAscii( szServiceName_TreeControlModel ); 92 } 93 94 Any UnoTreeModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const 95 { 96 switch( nPropId ) 97 { 98 case BASEPROPERTY_TREE_SELECTIONTYPE: 99 return Any( SelectionType_NONE ); 100 case BASEPROPERTY_ROW_HEIGHT: 101 return Any( sal_Int32( 0 ) ); 102 case BASEPROPERTY_TREE_DATAMODEL: 103 return Any( Reference< XTreeDataModel >( 0 ) ); 104 case BASEPROPERTY_TREE_EDITABLE: 105 case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: 106 return Any( sal_False ); 107 case BASEPROPERTY_TREE_ROOTDISPLAYED: 108 case BASEPROPERTY_TREE_SHOWSROOTHANDLES: 109 case BASEPROPERTY_TREE_SHOWSHANDLES: 110 return Any( sal_True ); 111 case BASEPROPERTY_DEFAULTCONTROL: 112 return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_TreeControl ) ); 113 default: 114 return UnoControlModel::ImplGetDefaultValue( nPropId ); 115 } 116 } 117 118 ::cppu::IPropertyArrayHelper& UnoTreeModel::getInfoHelper() 119 { 120 static UnoPropertyArrayHelper* pHelper = NULL; 121 if ( !pHelper ) 122 { 123 Sequence<sal_Int32> aIDs = ImplGetPropertyIds(); 124 pHelper = new UnoPropertyArrayHelper( aIDs ); 125 } 126 return *pHelper; 127 } 128 129 // XMultiPropertySet 130 Reference< XPropertySetInfo > UnoTreeModel::getPropertySetInfo( ) throw(RuntimeException) 131 { 132 static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); 133 return xInfo; 134 } 135 136 137 // ---------------------------------------------------- 138 // class UnoTreeControl 139 // ---------------------------------------------------- 140 UnoTreeControl::UnoTreeControl( const Reference< XMultiServiceFactory >& i_factory ) 141 : UnoTreeControl_Base( i_factory ) 142 , maSelectionListeners( *this ) 143 , maTreeExpansionListeners( *this ) 144 , maTreeEditListeners( *this ) 145 { 146 } 147 148 OUString UnoTreeControl::GetComponentServiceName() 149 { 150 return OUString::createFromAscii( "Tree" ); 151 } 152 153 // ------------------------------------------------------------------- 154 // ::com::sun::star::view::XSelectionSupplier 155 // ------------------------------------------------------------------- 156 157 sal_Bool SAL_CALL UnoTreeControl::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 158 { 159 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->select( rSelection ); 160 } 161 162 // ------------------------------------------------------------------- 163 164 Any SAL_CALL UnoTreeControl::getSelection() throw (RuntimeException) 165 { 166 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelection(); 167 } 168 169 // ------------------------------------------------------------------- 170 171 void SAL_CALL UnoTreeControl::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) 172 { 173 maSelectionListeners.addInterface( xListener ); 174 if( getPeer().is() && (maSelectionListeners.getLength() == 1) ) 175 { 176 // maSelectionListeners acts as a proxy, 177 // add it to the peer if this is the first listener added to that proxy 178 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 179 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addSelectionChangeListener(&maSelectionListeners); 180 } 181 } 182 183 // ------------------------------------------------------------------- 184 185 void SAL_CALL UnoTreeControl::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) 186 { 187 if( getPeer().is() && (maSelectionListeners.getLength() == 1) ) 188 { 189 // maSelectionListeners acts as a proxy, 190 // remove it from the peer if this is the last listener removed from that proxy 191 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 192 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelectionChangeListener(&maSelectionListeners); 193 } 194 maSelectionListeners.removeInterface( xListener ); 195 } 196 197 // ------------------------------------------------------------------- 198 // ::com::sun::star::view::XMultiSelectionSupplier 199 // ------------------------------------------------------------------- 200 201 sal_Bool SAL_CALL UnoTreeControl::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 202 { 203 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->addSelection(rSelection); 204 } 205 206 // ------------------------------------------------------------------- 207 208 void SAL_CALL UnoTreeControl::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 209 { 210 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 211 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelection(rSelection); 212 } 213 214 // ------------------------------------------------------------------- 215 216 void SAL_CALL UnoTreeControl::clearSelection() throw (RuntimeException) 217 { 218 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 219 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->clearSelection(); 220 } 221 222 // ------------------------------------------------------------------- 223 224 sal_Int32 SAL_CALL UnoTreeControl::getSelectionCount() throw (RuntimeException) 225 { 226 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelectionCount(); 227 } 228 229 // ------------------------------------------------------------------- 230 231 Reference< XEnumeration > SAL_CALL UnoTreeControl::createSelectionEnumeration() throw (RuntimeException) 232 { 233 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createSelectionEnumeration(); 234 } 235 236 // ------------------------------------------------------------------- 237 238 Reference< XEnumeration > SAL_CALL UnoTreeControl::createReverseSelectionEnumeration() throw (RuntimeException) 239 { 240 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createReverseSelectionEnumeration(); 241 } 242 243 // -------------------------------------------------------------------- 244 // XTreeControl 245 // -------------------------------------------------------------------- 246 247 OUString SAL_CALL UnoTreeControl::getDefaultExpandedGraphicURL() throw (RuntimeException) 248 { 249 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultExpandedGraphicURL(); 250 } 251 252 // ------------------------------------------------------------------- 253 254 void SAL_CALL UnoTreeControl::setDefaultExpandedGraphicURL( const OUString& _defaultexpansiongraphicurl ) throw (RuntimeException) 255 { 256 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 257 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultExpandedGraphicURL(_defaultexpansiongraphicurl); 258 } 259 260 // ------------------------------------------------------------------- 261 262 OUString SAL_CALL UnoTreeControl::getDefaultCollapsedGraphicURL() throw (RuntimeException) 263 { 264 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultCollapsedGraphicURL(); 265 } 266 267 // ------------------------------------------------------------------- 268 269 void SAL_CALL UnoTreeControl::setDefaultCollapsedGraphicURL( const OUString& _defaultcollapsedgraphicurl ) throw (RuntimeException) 270 { 271 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 272 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultCollapsedGraphicURL(_defaultcollapsedgraphicurl); 273 } 274 275 // ------------------------------------------------------------------- 276 277 sal_Bool SAL_CALL UnoTreeControl::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 278 { 279 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeExpanded(xNode); 280 } 281 282 // ------------------------------------------------------------------- 283 284 sal_Bool SAL_CALL UnoTreeControl::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 285 { 286 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeCollapsed(xNode); 287 } 288 289 // ------------------------------------------------------------------- 290 291 void SAL_CALL UnoTreeControl::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 292 { 293 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 294 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->makeNodeVisible(xNode); 295 } 296 297 // ------------------------------------------------------------------- 298 299 sal_Bool SAL_CALL UnoTreeControl::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 300 { 301 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeVisible(xNode); 302 } 303 304 // ------------------------------------------------------------------- 305 306 void SAL_CALL UnoTreeControl::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 307 { 308 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 309 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->expandNode(xNode); 310 } 311 312 // ------------------------------------------------------------------- 313 314 void SAL_CALL UnoTreeControl::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 315 { 316 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 317 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->collapseNode(xNode); 318 } 319 320 // ------------------------------------------------------------------- 321 322 void SAL_CALL UnoTreeControl::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) 323 { 324 maTreeExpansionListeners.addInterface( xListener ); 325 if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) ) 326 { 327 // maSelectionListeners acts as a proxy, 328 // add it to the peer if this is the first listener added to that proxy 329 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 330 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeExpansionListener(&maTreeExpansionListeners); 331 } 332 } 333 334 // ------------------------------------------------------------------- 335 336 void SAL_CALL UnoTreeControl::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) 337 { 338 if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) ) 339 { 340 // maSelectionListeners acts as a proxy, 341 // remove it from the peer if this is the last listener removed from that proxy 342 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 343 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeExpansionListener(&maTreeExpansionListeners); 344 } 345 maTreeExpansionListeners.removeInterface( xListener ); 346 } 347 348 // ------------------------------------------------------------------- 349 350 Reference< XTreeNode > SAL_CALL UnoTreeControl::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) 351 { 352 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getNodeForLocation(x,y); 353 } 354 355 // ------------------------------------------------------------------- 356 357 Reference< XTreeNode > SAL_CALL UnoTreeControl::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) 358 { 359 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getClosestNodeForLocation(x,y); 360 } 361 362 // ------------------------------------------------------------------- 363 364 awt::Rectangle SAL_CALL UnoTreeControl::getNodeRect( const Reference< XTreeNode >& Node ) throw (IllegalArgumentException, RuntimeException) 365 { 366 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getNodeRect( Node ); 367 } 368 369 // ------------------------------------------------------------------- 370 371 sal_Bool SAL_CALL UnoTreeControl::isEditing( ) throw (RuntimeException) 372 { 373 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isEditing(); 374 } 375 376 // ------------------------------------------------------------------- 377 378 sal_Bool SAL_CALL UnoTreeControl::stopEditing() throw (RuntimeException) 379 { 380 return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->stopEditing(); 381 } 382 383 // ------------------------------------------------------------------- 384 385 void SAL_CALL UnoTreeControl::cancelEditing() throw (RuntimeException) 386 { 387 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 388 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->cancelEditing(); 389 } 390 391 // ------------------------------------------------------------------- 392 393 void SAL_CALL UnoTreeControl::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) 394 { 395 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 396 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->startEditingAtNode(xNode); 397 } 398 399 // ------------------------------------------------------------------- 400 401 void SAL_CALL UnoTreeControl::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) 402 { 403 maTreeEditListeners.addInterface( xListener ); 404 if( getPeer().is() && (maTreeEditListeners.getLength() == 1) ) 405 { 406 // maSelectionListeners acts as a proxy, 407 // add it to the peer if this is the first listener added to that proxy 408 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 409 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeEditListener(&maTreeEditListeners); 410 } 411 } 412 413 // ------------------------------------------------------------------- 414 415 void SAL_CALL UnoTreeControl::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) 416 { 417 if( getPeer().is() && (maTreeEditListeners.getLength() == 1) ) 418 { 419 // maSelectionListeners acts as a proxy, 420 // remove it from the peer if this is the last listener removed from that proxy 421 Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer()); 422 Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeEditListener(&maTreeEditListeners); 423 } 424 maTreeEditListeners.removeInterface( xListener ); 425 } 426 427 // ------------------------------------------------------------------- 428 // XComponent 429 // ------------------------------------------------------------------- 430 431 void SAL_CALL UnoTreeControl::dispose( ) throw(RuntimeException) 432 { 433 lang::EventObject aEvt; 434 aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); 435 maSelectionListeners.disposeAndClear( aEvt ); 436 maTreeExpansionListeners.disposeAndClear( aEvt ); 437 UnoControl::dispose(); 438 } 439 440 void UnoTreeControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer > & rParentPeer ) throw(uno::RuntimeException) 441 { 442 UnoControlBase::createPeer( rxToolkit, rParentPeer ); 443 444 Reference< XTreeControl > xTree( getPeer(), UNO_QUERY_THROW ); 445 if( maSelectionListeners.getLength() ) 446 xTree->addSelectionChangeListener( &maSelectionListeners ); 447 if( maTreeExpansionListeners.getLength() ) 448 xTree->addTreeExpansionListener( &maTreeExpansionListeners ); 449 } 450 451 } 452 453 Reference< XInterface > SAL_CALL TreeControl_CreateInstance( const Reference< XMultiServiceFactory >& i_factory ) 454 { 455 return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeControl( i_factory ) ); 456 } 457 458 Reference< XInterface > SAL_CALL TreeControlModel_CreateInstance( const Reference< XMultiServiceFactory >& i_factory ) 459 { 460 return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeModel( i_factory ) ); 461 } 462 463 void SAL_CALL TreeEditListenerMultiplexer::nodeEditing( const Reference< XTreeNode >& Node ) throw (RuntimeException, ::com::sun::star::util::VetoException) 464 { 465 ::cppu::OInterfaceIteratorHelper aIt( *this ); 466 while( aIt.hasMoreElements() ) 467 { 468 Reference< XTreeEditListener > xListener(static_cast< XTreeEditListener* >( aIt.next() ) ); 469 try 470 { 471 xListener->nodeEditing( Node ); 472 } 473 catch( DisposedException& e ) 474 { 475 OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" ); 476 if ( e.Context == xListener || !e.Context.is() ) 477 aIt.remove(); 478 } 479 catch( RuntimeException& e ) 480 { 481 (void)e; 482 DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEditing, e ) 483 } 484 } 485 } 486 487 void SAL_CALL TreeEditListenerMultiplexer::nodeEdited( const Reference< XTreeNode >& Node, const OUString& NewText ) throw (RuntimeException) 488 { 489 ::cppu::OInterfaceIteratorHelper aIt( *this ); 490 while( aIt.hasMoreElements() ) 491 { 492 Reference< XTreeEditListener > xListener( static_cast< XTreeEditListener* >( aIt.next() ) ); 493 try 494 { 495 xListener->nodeEdited( Node, NewText ); 496 } 497 catch( DisposedException& e ) 498 { 499 OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" ); 500 if ( e.Context == xListener || !e.Context.is() ) 501 aIt.remove(); 502 } 503 catch( RuntimeException& e ) 504 { 505 (void)e; 506 DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEdited, e ) 507 } 508 } 509 } 510