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_svtools.hxx" 30 31 #define _SVTREEBX_CXX 32 #include <tools/debug.hxx> 33 #include <com/sun/star/lang/XServiceInfo.hpp> 34 #include <com/sun/star/lang/DisposedException.hpp> 35 #include <com/sun/star/view/SelectionType.hpp> 36 #include <toolkit/helper/property.hxx> 37 #include <toolkit/helper/vclunohelper.hxx> 38 39 #include <com/sun/star/awt/tree/XMutableTreeNode.hpp> 40 #include <treecontrolpeer.hxx> 41 #include <comphelper/processfactory.hxx> 42 43 #include <rtl/ref.hxx> 44 #include <vcl/graph.hxx> 45 #include <svtools/svtreebx.hxx> 46 47 #include <map> 48 49 using ::rtl::OUString; 50 using namespace ::com::sun::star; 51 using namespace ::com::sun::star::uno; 52 using namespace ::com::sun::star::lang; 53 using namespace ::com::sun::star::awt::tree; 54 using namespace ::com::sun::star::beans; 55 using namespace ::com::sun::star::view; 56 using namespace ::com::sun::star::container; 57 using namespace ::com::sun::star::util; 58 using namespace ::com::sun::star::graphic; 59 60 #define O(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) 61 62 struct LockGuard 63 { 64 public: 65 LockGuard( sal_Int32& rLock ) 66 : mrLock( rLock ) 67 { 68 rLock++; 69 } 70 71 ~LockGuard() 72 { 73 mrLock--; 74 } 75 76 sal_Int32& mrLock; 77 }; 78 79 // -------------------------------------------------------------------- 80 81 class ImplGraphicItem : public SvLBoxBmp 82 { 83 public: 84 ImplGraphicItem( SvLBoxEntry* pEntry, sal_uInt16 nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {} 85 86 OUString msGraphicURL; 87 }; 88 89 // -------------------------------------------------------------------- 90 91 class ImplContextGraphicItem : public SvLBoxContextBmp 92 { 93 public: 94 ImplContextGraphicItem( SvLBoxEntry* pEntry,sal_uInt16 nFlags,Image& rI1,Image& rI2, sal_uInt16 nEntryFlagsBmp1) 95 : SvLBoxContextBmp( pEntry, nFlags, rI1, rI2, nEntryFlagsBmp1 ) {} 96 97 OUString msExpandedGraphicURL; 98 OUString msCollapsedGraphicURL; 99 }; 100 101 // -------------------------------------------------------------------- 102 103 class UnoTreeListBoxImpl : public SvTreeListBox 104 { 105 public: 106 UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ); 107 ~UnoTreeListBoxImpl(); 108 109 sal_uInt32 insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos=LIST_APPEND ); 110 111 virtual void RequestingChilds( SvLBoxEntry* pParent ); 112 113 virtual sal_Bool EditingEntry( SvLBoxEntry* pEntry, Selection& ); 114 virtual sal_Bool EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ); 115 116 DECL_LINK( OnSelectionChangeHdl, UnoTreeListBoxImpl* ); 117 DECL_LINK( OnExpandingHdl, UnoTreeListBoxImpl* ); 118 DECL_LINK( OnExpandedHdl, UnoTreeListBoxImpl* ); 119 120 private: 121 rtl::Reference< TreeControlPeer > mxPeer; 122 }; 123 124 // -------------------------------------------------------------------- 125 126 class SVT_DLLPUBLIC UnoTreeListItem : public SvLBoxItem 127 { 128 public: 129 UnoTreeListItem( SvLBoxEntry* ); 130 UnoTreeListItem(); 131 virtual ~UnoTreeListItem(); 132 virtual sal_uInt16 IsA(); 133 void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* ); 134 OUString GetText() const; 135 void SetText( const OUString& rText ); 136 Image GetImage() const; 137 void SetImage( const Image& rImage ); 138 OUString GetGraphicURL() const; 139 void SetGraphicURL( const OUString& rGraphicURL ); 140 void Paint( const Point&, SvLBox& rDev, sal_uInt16 nFlags,SvLBoxEntry* ); 141 SvLBoxItem* Create() const; 142 void Clone( SvLBoxItem* pSource ); 143 144 private: 145 OUString maText; 146 OUString maGraphicURL; 147 Image maImage; 148 }; 149 150 // -------------------------------------------------------------------- 151 152 class UnoTreeListEntry : public SvLBoxEntry 153 { 154 public: 155 UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ); 156 virtual ~UnoTreeListEntry(); 157 158 Reference< XTreeNode > mxNode; 159 TreeControlPeer* mpPeer; 160 }; 161 162 // -------------------------------------------------------------------- 163 164 class TreeNodeMap : public std::map< Reference< XTreeNode >, UnoTreeListEntry* > 165 { 166 }; 167 168 // -------------------------------------------------------------------- 169 170 TreeControlPeer::TreeControlPeer() 171 : maSelectionListeners( *this ) 172 , maTreeExpansionListeners( *this ) 173 , maTreeEditListeners( *this ) 174 , mpTreeImpl( 0 ) 175 , mnEditLock( 0 ) 176 , mpTreeNodeMap( 0 ) 177 { 178 } 179 180 // -------------------------------------------------------------------- 181 182 TreeControlPeer::~TreeControlPeer() 183 { 184 if( mpTreeImpl ) 185 mpTreeImpl->Clear(); 186 delete mpTreeNodeMap; 187 } 188 189 // -------------------------------------------------------------------- 190 191 void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry ) 192 { 193 if( pEntry && pEntry->mxNode.is() ) 194 { 195 if( !mpTreeNodeMap ) 196 { 197 mpTreeNodeMap = new TreeNodeMap(); 198 } 199 200 (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry; 201 } 202 } 203 204 // -------------------------------------------------------------------- 205 206 void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry ) 207 { 208 if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() ) 209 { 210 TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) ); 211 if( aIter != mpTreeNodeMap->end() ) 212 { 213 mpTreeNodeMap->erase( aIter ); 214 } 215 } 216 } 217 218 // -------------------------------------------------------------------- 219 220 UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) throw( IllegalArgumentException ) 221 { 222 if( mpTreeNodeMap ) 223 { 224 TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) ); 225 if( aIter != mpTreeNodeMap->end() ) 226 return (*aIter).second; 227 } 228 229 if( bThrow ) 230 throw IllegalArgumentException(); 231 232 return 0; 233 } 234 235 // -------------------------------------------------------------------- 236 237 Window* TreeControlPeer::createVclControl( Window* pParent, sal_Int64 nWinStyle ) 238 { 239 mpTreeImpl = new UnoTreeListBoxImpl( this, pParent, nWinStyle ); 240 return mpTreeImpl; 241 } 242 243 // -------------------------------------------------------------------- 244 245 /** called from the UnoTreeListBoxImpl when it gets deleted */ 246 void TreeControlPeer::disposeControl() 247 { 248 delete mpTreeNodeMap; 249 mpTreeNodeMap = 0; 250 mpTreeImpl = 0; 251 } 252 253 // -------------------------------------------------------------------- 254 255 void TreeControlPeer::SetWindow( Window* pWindow ) 256 { 257 VCLXWindow::SetWindow( pWindow ); 258 } 259 260 // -------------------------------------------------------------------- 261 262 UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, sal_uLong nPos /* = LIST_APPEND */ ) 263 { 264 UnoTreeListEntry* pEntry = 0; 265 if( mpTreeImpl ) 266 { 267 Image aImage; 268 pEntry = new UnoTreeListEntry( xNode, this ); 269 ImplContextGraphicItem* pContextBmp= new ImplContextGraphicItem( pEntry,0, aImage, aImage, SVLISTENTRYFLAG_EXPANDED ); 270 271 pEntry->AddItem( pContextBmp ); 272 273 UnoTreeListItem * pUnoItem = new UnoTreeListItem( pEntry ); 274 275 if( xNode->getNodeGraphicURL().getLength() ) 276 { 277 pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() ); 278 Image aNodeImage; 279 loadImage( xNode->getNodeGraphicURL(), aNodeImage ); 280 pUnoItem->SetImage( aNodeImage ); 281 mpTreeImpl->AdjustEntryHeight( aNodeImage ); 282 } 283 284 pEntry->AddItem( pUnoItem ); 285 286 mpTreeImpl->insert( pEntry, pParent, nPos ); 287 288 if( msDefaultExpandedGraphicURL.getLength() ) 289 mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); 290 291 if( msDefaultCollapsedGraphicURL.getLength() ) 292 mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); 293 294 updateEntry( pEntry ); 295 } 296 return pEntry; 297 } 298 299 // -------------------------------------------------------------------- 300 301 bool TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry ) 302 { 303 bool bChanged = false; 304 if( pEntry && pEntry->mxNode.is() && mpTreeImpl ) 305 { 306 const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) ); 307 UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( pEntry->GetItem( 1 ) ); 308 if( pUnoItem ) 309 { 310 if( aValue != pUnoItem->GetText() ) 311 { 312 pUnoItem->SetText( aValue ); 313 bChanged = true; 314 } 315 316 if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() ) 317 { 318 Image aImage; 319 if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) ) 320 { 321 pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() ); 322 pUnoItem->SetImage( aImage ); 323 mpTreeImpl->AdjustEntryHeight( aImage ); 324 bChanged = true; 325 } 326 } 327 } 328 329 if( (pEntry->mxNode->hasChildrenOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == sal_True) ) 330 { 331 pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildrenOnDemand() ? sal_True : sal_False ); 332 bChanged = true; 333 } 334 335 ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); 336 if( pContextGraphicItem ) 337 { 338 if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() ) 339 { 340 Image aImage; 341 if( loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) ) 342 { 343 pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL(); 344 mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage ); 345 bChanged = true; 346 } 347 } 348 if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() ) 349 { 350 Image aImage; 351 if( loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) ) 352 { 353 pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL(); 354 mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage ); 355 bChanged = true; 356 } 357 } 358 } 359 360 if( bChanged ) 361 mpTreeImpl->GetModel()->InvalidateEntry( pEntry ); 362 } 363 364 return bChanged; 365 } 366 367 // -------------------------------------------------------------------- 368 369 void TreeControlPeer::onSelectionChanged() 370 { 371 Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 372 EventObject aEvent( xSource ); 373 maSelectionListeners.selectionChanged( aEvent ); 374 } 375 376 // -------------------------------------------------------------------- 377 378 void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode ) 379 { 380 try 381 { 382 Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 383 TreeExpansionEvent aEvent( xSource, xNode ); 384 maTreeExpansionListeners.requestChildNodes( aEvent ); 385 } 386 catch( Exception& ) 387 { 388 } 389 } 390 391 // -------------------------------------------------------------------- 392 393 bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding ) 394 { 395 try 396 { 397 Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 398 TreeExpansionEvent aEvent( xSource, xNode ); 399 if( bExpanding ) 400 { 401 maTreeExpansionListeners.treeExpanding( aEvent ); 402 } 403 else 404 { 405 maTreeExpansionListeners.treeCollapsing( aEvent ); 406 } 407 } 408 catch( Exception& ) 409 { 410 return false; 411 } 412 return true; 413 } 414 415 // -------------------------------------------------------------------- 416 417 void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding ) 418 { 419 try 420 { 421 Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); 422 TreeExpansionEvent aEvent( xSource, xNode ); 423 424 if( bExpanding ) 425 { 426 maTreeExpansionListeners.treeExpanded( aEvent ); 427 } 428 else 429 { 430 maTreeExpansionListeners.treeCollapsed( aEvent ); 431 } 432 } 433 catch( Exception& ) 434 { 435 } 436 } 437 438 // -------------------------------------------------------------------- 439 440 void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) 441 { 442 rTree.Clear(); 443 444 if( xDataModel.is() ) 445 { 446 Reference< XTreeNode > xRootNode( xDataModel->getRoot() ); 447 if( xRootNode.is() ) 448 { 449 if( mbIsRootDisplayed ) 450 { 451 addNode( rTree, xRootNode, 0 ); 452 } 453 else 454 { 455 const sal_Int32 nChildCount = xRootNode->getChildCount(); 456 for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) 457 addNode( rTree, xRootNode->getChildAt( nChild ), 0 ); 458 } 459 } 460 } 461 } 462 463 // -------------------------------------------------------------------- 464 465 void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry ) 466 { 467 if( xNode.is() ) 468 { 469 UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, LIST_APPEND ); 470 const sal_Int32 nChildCount = xNode->getChildCount(); 471 for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) 472 addNode( rTree, xNode->getChildAt( nChild ), pEntry ); 473 } 474 } 475 476 // -------------------------------------------------------------------- 477 478 UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException ) 479 { 480 if( !mpTreeImpl ) 481 throw DisposedException(); 482 return *mpTreeImpl; 483 } 484 485 // -------------------------------------------------------------------- 486 487 void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) throw( RuntimeException, IllegalArgumentException ) 488 { 489 ::vos::OGuard aGuard( GetMutex() ); 490 491 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 492 493 Reference< XTreeNode > xTempNode; 494 Sequence< XTreeNode > aTempSeq; 495 496 const Reference< XTreeNode > *pNodes = 0; 497 sal_Int32 nCount = 0; 498 499 if( rSelection.hasValue() ) 500 { 501 switch( rSelection.getValueTypeClass() ) 502 { 503 case TypeClass_INTERFACE: 504 { 505 rSelection >>= xTempNode; 506 if( xTempNode.is() ) 507 { 508 nCount = 1; 509 pNodes = &xTempNode; 510 } 511 break; 512 } 513 case TypeClass_SEQUENCE: 514 { 515 if( rSelection.getValueType() == ::getCppuType( (const Sequence< Reference< XTreeNode > > *) 0 ) ) 516 { 517 const Sequence< Reference< XTreeNode > >& rSeq( *(const Sequence< Reference< XTreeNode > > *)rSelection.getValue() ); 518 nCount = rSeq.getLength(); 519 if( nCount ) 520 pNodes = rSeq.getConstArray(); 521 } 522 break; 523 } 524 default: 525 break; 526 } 527 528 if( nCount == 0 ) 529 throw IllegalArgumentException(); 530 } 531 532 if( bSetSelection ) 533 rTree.SelectAll( sal_False ); 534 535 if( pNodes && nCount ) 536 { 537 while( nCount-- ) 538 { 539 UnoTreeListEntry* pEntry = getEntry( *pNodes++ ); 540 rTree.Select( pEntry, bSelect ? sal_True : sal_False ); 541 } 542 } 543 } 544 545 // ------------------------------------------------------------------- 546 // ::com::sun::star::view::XSelectionSupplier 547 // ------------------------------------------------------------------- 548 549 sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 550 { 551 ::vos::OGuard aGuard( GetMutex() ); 552 ChangeNodesSelection( rSelection, true, true ); 553 return sal_True; 554 } 555 556 // ------------------------------------------------------------------- 557 558 Any SAL_CALL TreeControlPeer::getSelection() throw (RuntimeException) 559 { 560 ::vos::OGuard aGuard( GetMutex() ); 561 562 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 563 564 Any aRet; 565 566 sal_uLong nSelectionCount = rTree.GetSelectionCount(); 567 if( nSelectionCount == 1 ) 568 { 569 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); 570 if( pEntry && pEntry->mxNode.is() ) 571 aRet <<= pEntry->mxNode; 572 } 573 else if( nSelectionCount > 1 ) 574 { 575 Sequence< Reference< XTreeNode > > aSelection( nSelectionCount ); 576 Reference< XTreeNode >* pNodes = aSelection.getArray(); 577 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); 578 while( pEntry && nSelectionCount ) 579 { 580 *pNodes++ = pEntry->mxNode; 581 pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); 582 --nSelectionCount; 583 } 584 585 OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); 586 aRet <<= aSelection; 587 } 588 589 return aRet; 590 } 591 592 // ------------------------------------------------------------------- 593 594 void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) 595 { 596 maSelectionListeners.addInterface( xListener ); 597 } 598 599 // ------------------------------------------------------------------- 600 601 void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) 602 { 603 maSelectionListeners.addInterface( xListener ); 604 } 605 606 // ------------------------------------------------------------------- 607 // ::com::sun::star::view::XMultiSelectionSupplier 608 // ------------------------------------------------------------------- 609 610 sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 611 { 612 ChangeNodesSelection( rSelection, true, false ); 613 return sal_True; 614 } 615 616 // ------------------------------------------------------------------- 617 618 void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) 619 { 620 ChangeNodesSelection( rSelection, false, false ); 621 } 622 623 // ------------------------------------------------------------------- 624 625 void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException) 626 { 627 ::vos::OGuard aGuard( GetMutex() ); 628 getTreeListBoxOrThrow().SelectAll( sal_False ); 629 } 630 631 // ------------------------------------------------------------------- 632 633 sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() throw (RuntimeException) 634 { 635 ::vos::OGuard aGuard( GetMutex() ); 636 return getTreeListBoxOrThrow().GetSelectionCount(); 637 } 638 639 // ------------------------------------------------------------------- 640 641 class TreeSelectionEnumeration : public ::cppu::WeakImplHelper1< XEnumeration > 642 { 643 public: 644 TreeSelectionEnumeration( std::list< Any >& rSelection ); 645 virtual ::sal_Bool SAL_CALL hasMoreElements() throw (RuntimeException); 646 virtual Any SAL_CALL nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException); 647 648 std::list< Any > maSelection; 649 std::list< Any >::iterator maIter; 650 }; 651 652 // ------------------------------------------------------------------- 653 654 TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection ) 655 { 656 maSelection.swap( rSelection ); 657 maIter = maSelection.begin(); 658 } 659 660 // ------------------------------------------------------------------- 661 662 ::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException) 663 { 664 return maIter != maSelection.end(); 665 } 666 667 // ------------------------------------------------------------------- 668 669 Any SAL_CALL TreeSelectionEnumeration::nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException) 670 { 671 if( maIter == maSelection.end() ) 672 throw NoSuchElementException(); 673 674 return (*maIter++); 675 } 676 677 // ------------------------------------------------------------------- 678 679 Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() throw (RuntimeException) 680 { 681 ::vos::OGuard aGuard( GetMutex() ); 682 683 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 684 685 sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); 686 std::list< Any > aSelection( nSelectionCount ); 687 688 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); 689 while( pEntry && nSelectionCount ) 690 { 691 aSelection.push_back( Any( pEntry->mxNode ) ); 692 pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); 693 --nSelectionCount; 694 } 695 696 OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); 697 698 return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); 699 } 700 701 // ------------------------------------------------------------------- 702 703 Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() throw (RuntimeException) 704 { 705 ::vos::OGuard aGuard( GetMutex() ); 706 707 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 708 709 sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); 710 std::list< Any > aSelection; 711 712 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); 713 while( pEntry && nSelectionCount ) 714 { 715 aSelection.push_front( Any( pEntry->mxNode ) ); 716 pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); 717 --nSelectionCount; 718 } 719 720 OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); 721 722 return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); 723 } 724 725 // -------------------------------------------------------------------- 726 // ::com::sun::star::awt::XTreeControl 727 // -------------------------------------------------------------------- 728 729 OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException) 730 { 731 ::vos::OGuard aGuard( GetMutex() ); 732 return msDefaultExpandedGraphicURL; 733 } 734 735 // -------------------------------------------------------------------- 736 737 void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const ::rtl::OUString& sDefaultExpandedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) 738 { 739 ::vos::OGuard aGuard( GetMutex() ); 740 if( msDefaultExpandedGraphicURL != sDefaultExpandedGraphicURL ) 741 { 742 if( sDefaultExpandedGraphicURL.getLength() ) 743 loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage ); 744 else 745 maDefaultExpandedImage = Image(); 746 747 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 748 749 SvLBoxEntry* pEntry = rTree.First(); 750 while( pEntry ) 751 { 752 ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); 753 if( pContextGraphicItem ) 754 { 755 if( pContextGraphicItem->msExpandedGraphicURL.getLength() == 0 ) 756 rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); 757 } 758 pEntry = rTree.Next( pEntry ); 759 } 760 761 msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL; 762 } 763 } 764 765 // -------------------------------------------------------------------- 766 767 OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException) 768 { 769 ::vos::OGuard aGuard( GetMutex() ); 770 return msDefaultCollapsedGraphicURL; 771 } 772 773 // -------------------------------------------------------------------- 774 775 void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const ::rtl::OUString& sDefaultCollapsedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) 776 { 777 ::vos::OGuard aGuard( GetMutex() ); 778 if( msDefaultCollapsedGraphicURL != sDefaultCollapsedGraphicURL ) 779 { 780 if( sDefaultCollapsedGraphicURL.getLength() ) 781 loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage ); 782 else 783 maDefaultCollapsedImage = Image(); 784 785 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 786 787 SvLBoxEntry* pEntry = rTree.First(); 788 while( pEntry ) 789 { 790 ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); 791 if( pContextGraphicItem ) 792 { 793 if( pContextGraphicItem->msCollapsedGraphicURL.getLength() == 0 ) 794 rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); 795 } 796 pEntry = rTree.Next( pEntry ); 797 } 798 799 msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL; 800 } 801 } 802 803 // -------------------------------------------------------------------- 804 805 sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 806 { 807 ::vos::OGuard aGuard( GetMutex() ); 808 809 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 810 UnoTreeListEntry* pEntry = getEntry( xNode ); 811 return ( pEntry && rTree.IsExpanded( pEntry ) ) ? sal_True : sal_False; 812 } 813 814 // ------------------------------------------------------------------- 815 816 sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 817 { 818 ::vos::OGuard aGuard( GetMutex() ); 819 return !isNodeExpanded( xNode ); 820 } 821 822 // ------------------------------------------------------------------- 823 824 void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 825 { 826 ::vos::OGuard aGuard( GetMutex() ); 827 828 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 829 UnoTreeListEntry* pEntry = getEntry( xNode ); 830 if( pEntry ) 831 rTree.MakeVisible( pEntry ); 832 } 833 834 // ------------------------------------------------------------------- 835 836 sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) 837 { 838 ::vos::OGuard aGuard( GetMutex() ); 839 840 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 841 UnoTreeListEntry* pEntry = getEntry( xNode ); 842 return ( pEntry && rTree.IsEntryVisible( pEntry ) ) ? sal_True : sal_False; 843 } 844 845 // ------------------------------------------------------------------- 846 847 void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 848 { 849 ::vos::OGuard aGuard( GetMutex() ); 850 851 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 852 UnoTreeListEntry* pEntry = getEntry( xNode ); 853 if( pEntry ) 854 rTree.Expand( pEntry ); 855 } 856 857 // ------------------------------------------------------------------- 858 859 void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) 860 { 861 ::vos::OGuard aGuard( GetMutex() ); 862 863 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 864 UnoTreeListEntry* pEntry = getEntry( xNode ); 865 if( pEntry ) 866 rTree.Collapse( pEntry ); 867 } 868 869 // ------------------------------------------------------------------- 870 871 void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) 872 { 873 maTreeExpansionListeners.addInterface( xListener ); 874 } 875 876 // ------------------------------------------------------------------- 877 878 void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) 879 { 880 maTreeExpansionListeners.removeInterface( xListener ); 881 } 882 883 // ------------------------------------------------------------------- 884 885 Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) 886 { 887 ::vos::OGuard aGuard( GetMutex() ); 888 889 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 890 891 Reference< XTreeNode > xNode; 892 893 const Point aPos( x, y ); 894 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) ); 895 if( pEntry ) 896 xNode = pEntry->mxNode; 897 898 return xNode; 899 } 900 901 // ------------------------------------------------------------------- 902 903 Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) 904 { 905 ::vos::OGuard aGuard( GetMutex() ); 906 907 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 908 909 Reference< XTreeNode > xNode; 910 911 const Point aPos( x, y ); 912 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) ); 913 if( pEntry ) 914 xNode = pEntry->mxNode; 915 916 return xNode; 917 } 918 919 // ------------------------------------------------------------------- 920 921 awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) throw (IllegalArgumentException, RuntimeException) 922 { 923 ::vos::OGuard aGuard( GetMutex() ); 924 925 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 926 UnoTreeListEntry* pEntry = getEntry( i_Node, true ); 927 928 ::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) ); 929 return VCLUnoHelper::ConvertToAWTRect( aEntryRect ); 930 } 931 932 // ------------------------------------------------------------------- 933 934 sal_Bool SAL_CALL TreeControlPeer::isEditing( ) throw (RuntimeException) 935 { 936 ::vos::OGuard aGuard( GetMutex() ); 937 938 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 939 return rTree.IsEditingActive() ? sal_True : sal_False; 940 } 941 942 // ------------------------------------------------------------------- 943 944 sal_Bool SAL_CALL TreeControlPeer::stopEditing() throw (RuntimeException) 945 { 946 ::vos::OGuard aGuard( GetMutex() ); 947 948 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 949 if( rTree.IsEditingActive() ) 950 { 951 rTree.EndEditing(sal_False); 952 return sal_True; 953 } 954 else 955 { 956 return sal_False; 957 } 958 } 959 960 // ------------------------------------------------------------------- 961 962 void SAL_CALL TreeControlPeer::cancelEditing( ) throw (RuntimeException) 963 { 964 ::vos::OGuard aGuard( GetMutex() ); 965 966 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 967 rTree.EndEditing(sal_False); 968 } 969 970 // ------------------------------------------------------------------- 971 972 void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) 973 { 974 ::vos::OGuard aGuard( GetMutex() ); 975 976 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 977 UnoTreeListEntry* pEntry = getEntry( xNode ); 978 rTree.EditEntry( pEntry ); 979 } 980 981 void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) 982 { 983 maTreeEditListeners.addInterface( xListener ); 984 } 985 986 void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) 987 { 988 maTreeEditListeners.removeInterface( xListener ); 989 } 990 991 bool TreeControlPeer::onEditingEntry( UnoTreeListEntry* pEntry ) 992 { 993 if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0) ) 994 { 995 try 996 { 997 maTreeEditListeners.nodeEditing( pEntry->mxNode ); 998 } 999 catch( VetoException& ) 1000 { 1001 return false; 1002 } 1003 catch( Exception& ) 1004 { 1005 } 1006 } 1007 return true; 1008 } 1009 1010 bool TreeControlPeer::onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText ) 1011 { 1012 if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try 1013 { 1014 LockGuard aLockGuard( mnEditLock ); 1015 const OUString aNewText( rNewText ); 1016 if( maTreeEditListeners.getLength() > 0 ) 1017 { 1018 maTreeEditListeners.nodeEdited( pEntry->mxNode, aNewText ); 1019 return false; 1020 } 1021 else 1022 { 1023 Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY ); 1024 if( xMutableNode.is() ) 1025 xMutableNode->setDisplayValue( Any( aNewText ) ); 1026 else 1027 return false; 1028 } 1029 1030 } 1031 catch( Exception& ) 1032 { 1033 } 1034 1035 return true; 1036 } 1037 1038 // -------------------------------------------------------------------- 1039 // ::com::sun::star::awt::tree::TreeDataModelListener 1040 // -------------------------------------------------------------------- 1041 1042 void SAL_CALL TreeControlPeer::treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) 1043 { 1044 ::vos::OGuard aGuard( GetMutex() ); 1045 1046 if( mnEditLock != 0 ) 1047 return; 1048 1049 updateTree( rEvent, true ); 1050 } 1051 1052 void SAL_CALL TreeControlPeer::treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) 1053 { 1054 ::vos::OGuard aGuard( GetMutex() ); 1055 1056 if( mnEditLock != 0 ) 1057 return; 1058 1059 updateTree( rEvent, true ); 1060 } 1061 1062 void SAL_CALL TreeControlPeer::treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) 1063 { 1064 ::vos::OGuard aGuard( GetMutex() ); 1065 1066 if( mnEditLock != 0 ) 1067 return; 1068 1069 updateTree( rEvent, true ); 1070 } 1071 1072 void SAL_CALL TreeControlPeer::treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) 1073 { 1074 ::vos::OGuard aGuard( GetMutex() ); 1075 1076 if( mnEditLock != 0 ) 1077 return; 1078 1079 updateTree( rEvent, true ); 1080 } 1081 1082 void TreeControlPeer::updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive ) 1083 { 1084 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 1085 1086 Sequence< Reference< XTreeNode > > Nodes; 1087 Reference< XTreeNode > xNode( rEvent.ParentNode ); 1088 if( !xNode.is() && Nodes.getLength() ) 1089 { 1090 xNode = Nodes[0]; 1091 } 1092 1093 if( xNode.is() ) 1094 updateNode( rTree, xNode, bRecursive ); 1095 } 1096 1097 void TreeControlPeer::updateNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, bool bRecursive ) 1098 { 1099 if( xNode.is() ) 1100 { 1101 UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); 1102 1103 if( !pNodeEntry ) 1104 { 1105 Reference< XTreeNode > xParentNode( xNode->getParent() ); 1106 UnoTreeListEntry* pParentEntry = 0; 1107 sal_uLong nChild = LIST_APPEND; 1108 1109 if( xParentNode.is() ) 1110 { 1111 pParentEntry = getEntry( xParentNode ); 1112 nChild = xParentNode->getIndex( xNode ); 1113 } 1114 1115 pNodeEntry = createEntry( xNode, pParentEntry, nChild ); 1116 } 1117 1118 if( bRecursive ) 1119 updateChildNodes( rTree, xNode, pNodeEntry ); 1120 } 1121 } 1122 1123 void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry ) 1124 { 1125 if( xParentNode.is() && pParentEntry ) 1126 { 1127 UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) ); 1128 1129 const sal_Int32 nChildCount = xParentNode->getChildCount(); 1130 for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) 1131 { 1132 Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) ); 1133 if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) ) 1134 { 1135 UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); 1136 if( pNodeEntry == 0 ) 1137 { 1138 // child node is not yet part of the tree, add it 1139 pCurrentChild = createEntry( xNode, pParentEntry, nChild ); 1140 } 1141 else if( pNodeEntry != pCurrentChild ) 1142 { 1143 // node is already part of the tree, but not on the correct position 1144 rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild ); 1145 pCurrentChild = pNodeEntry; 1146 updateEntry( pCurrentChild ); 1147 } 1148 } 1149 else 1150 { 1151 // child node has entry and entry is equal to current entry, 1152 // so no structural changes happened 1153 updateEntry( pCurrentChild ); 1154 } 1155 1156 pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); 1157 } 1158 1159 // check if we have entries without nodes left, we need to remove them 1160 while( pCurrentChild ) 1161 { 1162 UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); 1163 rTree.GetModel()->Remove( pCurrentChild ); 1164 pCurrentChild = pNextChild; 1165 } 1166 } 1167 } 1168 1169 OUString TreeControlPeer::getEntryString( const Any& rValue ) 1170 { 1171 OUString sValue; 1172 if( rValue.hasValue() ) 1173 { 1174 switch( rValue.getValueTypeClass() ) 1175 { 1176 case TypeClass_SHORT: 1177 case TypeClass_LONG: 1178 { 1179 sal_Int32 nValue = 0; 1180 if( rValue >>= nValue ) 1181 sValue = OUString::valueOf( nValue ); 1182 break; 1183 } 1184 case TypeClass_BYTE: 1185 case TypeClass_UNSIGNED_SHORT: 1186 case TypeClass_UNSIGNED_LONG: 1187 { 1188 sal_uInt32 nValue = 0; 1189 if( rValue >>= nValue ) 1190 sValue = OUString::valueOf( (sal_Int64)nValue ); 1191 break; 1192 } 1193 case TypeClass_HYPER: 1194 { 1195 sal_Int64 nValue = 0; 1196 if( rValue >>= nValue ) 1197 sValue = OUString::valueOf( nValue ); 1198 break; 1199 } 1200 case TypeClass_UNSIGNED_HYPER: 1201 { 1202 sal_uInt64 nValue = 0; 1203 if( rValue >>= nValue ) 1204 sValue = OUString::valueOf( (sal_Int64)nValue ); 1205 break; 1206 } 1207 case TypeClass_FLOAT: 1208 case TypeClass_DOUBLE: 1209 { 1210 double fValue = 0.0; 1211 if( rValue >>= fValue ) 1212 sValue = OUString::valueOf( fValue ); 1213 break; 1214 } 1215 case TypeClass_STRING: 1216 rValue >>= sValue; 1217 break; 1218 /* 1219 case TypeClass_INTERFACE: 1220 // @todo 1221 break; 1222 case TypeClass_SEQUENCE: 1223 { 1224 Sequence< Any > aValues; 1225 if( aValue >>= aValues ) 1226 { 1227 updateEntry( SvLBoxEntry& rEntry, aValues ); 1228 return; 1229 } 1230 } 1231 break; 1232 */ 1233 default: 1234 break; 1235 } 1236 } 1237 return sValue; 1238 } 1239 1240 // XEventListener 1241 void SAL_CALL TreeControlPeer::disposing( const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException) 1242 { 1243 // model is disposed, so we clear our tree 1244 ::vos::OGuard aGuard( GetMutex() ); 1245 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 1246 rTree.Clear(); 1247 mxDataModel.clear(); 1248 } 1249 1250 void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) 1251 { 1252 if( xDataModel.is() && (mxDataModel == xDataModel) ) 1253 return; // do nothing 1254 1255 Reference< XTreeDataModelListener > xListener( this ); 1256 1257 if( mxDataModel.is() ) 1258 mxDataModel->removeTreeDataModelListener( xListener ); 1259 1260 if( !xDataModel.is() ) 1261 { 1262 static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.DefaultTreeDataModel" ) ); 1263 Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); 1264 if( xORB.is() ) 1265 { 1266 mxDataModel.query( xORB->createInstance( aSN ) ); 1267 } 1268 } 1269 1270 mxDataModel = xDataModel; 1271 1272 fillTree( rTree, mxDataModel ); 1273 1274 if( mxDataModel.is() ) 1275 mxDataModel->addTreeDataModelListener( xListener ); 1276 } 1277 1278 // -------------------------------------------------------------------- 1279 // ::com::sun::star::awt::XLayoutConstrains 1280 // -------------------------------------------------------------------- 1281 1282 ::com::sun::star::awt::Size TreeControlPeer::getMinimumSize() throw(RuntimeException) 1283 { 1284 ::vos::OGuard aGuard( GetMutex() ); 1285 1286 ::com::sun::star::awt::Size aSz; 1287 /* todo 1288 MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); 1289 if ( pEdit ) 1290 aSz = AWTSize(pEdit->CalcMinimumSize()); 1291 */ 1292 return aSz; 1293 } 1294 1295 ::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException) 1296 { 1297 return getMinimumSize(); 1298 } 1299 1300 ::com::sun::star::awt::Size TreeControlPeer::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(RuntimeException) 1301 { 1302 ::vos::OGuard aGuard( GetMutex() ); 1303 1304 ::com::sun::star::awt::Size aSz = rNewSize; 1305 /* todo 1306 MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); 1307 if ( pEdit ) 1308 aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize ))); 1309 */ 1310 return aSz; 1311 } 1312 1313 // -------------------------------------------------------------------- 1314 // ::com::sun::star::awt::XVclWindowPeer 1315 // -------------------------------------------------------------------- 1316 1317 void TreeControlPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) 1318 { 1319 ::vos::OGuard aGuard( GetMutex() ); 1320 1321 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 1322 1323 switch( GetPropertyId( PropertyName ) ) 1324 { 1325 case BASEPROPERTY_HIDEINACTIVESELECTION: 1326 { 1327 sal_Bool bEnabled = sal_False; 1328 if ( aValue >>= bEnabled ) 1329 { 1330 WinBits nStyle = rTree.GetStyle(); 1331 if ( bEnabled ) 1332 nStyle |= WB_HIDESELECTION; 1333 else 1334 nStyle &= ~WB_HIDESELECTION; 1335 rTree.SetStyle( nStyle ); 1336 } 1337 } 1338 break; 1339 1340 case BASEPROPERTY_TREE_SELECTIONTYPE: 1341 { 1342 SelectionType eSelectionType; 1343 if( aValue >>= eSelectionType ) 1344 { 1345 SelectionMode eSelMode; 1346 switch( eSelectionType ) 1347 { 1348 case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; 1349 case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; 1350 case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; 1351 // case SelectionType_NONE: 1352 default: eSelMode = NO_SELECTION; break; 1353 } 1354 if( rTree.GetSelectionMode() != eSelMode ) 1355 rTree.SetSelectionMode( eSelMode ); 1356 } 1357 break; 1358 } 1359 1360 case BASEPROPERTY_TREE_DATAMODEL: 1361 onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) ); 1362 break; 1363 case BASEPROPERTY_ROW_HEIGHT: 1364 { 1365 sal_Int32 nHeight = 0; 1366 if( aValue >>= nHeight ) 1367 rTree.SetEntryHeight( (short)nHeight ); 1368 break; 1369 } 1370 case BASEPROPERTY_TREE_EDITABLE: 1371 { 1372 sal_Bool bEnabled = false; 1373 if( aValue >>= bEnabled ) 1374 rTree.EnableInplaceEditing( bEnabled ? sal_True : sal_False ); 1375 break; 1376 } 1377 case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: 1378 break; // @todo 1379 case BASEPROPERTY_TREE_ROOTDISPLAYED: 1380 { 1381 sal_Bool bDisplayed = false; 1382 if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) ) 1383 { 1384 onChangeRootDisplayed(bDisplayed); 1385 } 1386 break; 1387 } 1388 case BASEPROPERTY_TREE_SHOWSHANDLES: 1389 { 1390 sal_Bool bEnabled = false; 1391 if( aValue >>= bEnabled ) 1392 { 1393 WinBits nBits = rTree.GetStyle() & (~WB_HASLINES); 1394 if( bEnabled ) 1395 nBits |= WB_HASLINES; 1396 if( nBits != rTree.GetStyle() ) 1397 rTree.SetStyle( nBits ); 1398 } 1399 break; 1400 } 1401 case BASEPROPERTY_TREE_SHOWSROOTHANDLES: 1402 { 1403 sal_Bool bEnabled = false; 1404 if( aValue >>= bEnabled ) 1405 { 1406 WinBits nBits = rTree.GetStyle() & (~WB_HASLINESATROOT); 1407 if( bEnabled ) 1408 nBits |= WB_HASLINESATROOT; 1409 if( nBits != rTree.GetStyle() ) 1410 rTree.SetStyle( nBits ); 1411 } 1412 break; 1413 } 1414 default: 1415 VCLXWindow::setProperty( PropertyName, aValue ); 1416 break; 1417 } 1418 } 1419 1420 Any TreeControlPeer::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) 1421 { 1422 ::vos::OGuard aGuard( GetMutex() ); 1423 1424 const sal_uInt16 nPropId = GetPropertyId( PropertyName ); 1425 if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) ) 1426 { 1427 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 1428 switch(nPropId) 1429 { 1430 case BASEPROPERTY_HIDEINACTIVESELECTION: 1431 return Any( ( rTree.GetStyle() & WB_HIDESELECTION ) != 0 ? sal_True : sal_False ); 1432 1433 case BASEPROPERTY_TREE_SELECTIONTYPE: 1434 { 1435 SelectionType eSelectionType; 1436 1437 SelectionMode eSelMode = rTree.GetSelectionMode(); 1438 switch( eSelMode ) 1439 { 1440 case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; 1441 case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; 1442 case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; 1443 // case NO_SELECTION: 1444 default: eSelectionType = SelectionType_NONE; break; 1445 } 1446 return Any( eSelectionType ); 1447 } 1448 case BASEPROPERTY_ROW_HEIGHT: 1449 return Any( (sal_Int32)rTree.GetEntryHeight() ); 1450 case BASEPROPERTY_TREE_DATAMODEL: 1451 return Any( mxDataModel ); 1452 case BASEPROPERTY_TREE_EDITABLE: 1453 return Any( rTree.IsInplaceEditingEnabled() ? sal_True : sal_False ); 1454 case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: 1455 return Any( sal_True ); // @todo 1456 case BASEPROPERTY_TREE_ROOTDISPLAYED: 1457 return Any( mbIsRootDisplayed ); 1458 case BASEPROPERTY_TREE_SHOWSHANDLES: 1459 return Any( (rTree.GetStyle() & WB_HASLINES) != 0 ? sal_True : sal_False ); 1460 case BASEPROPERTY_TREE_SHOWSROOTHANDLES: 1461 return Any( (rTree.GetStyle() & WB_HASLINESATROOT) != 0 ? sal_True : sal_False ); 1462 } 1463 } 1464 return VCLXWindow::getProperty( PropertyName ); 1465 } 1466 1467 void TreeControlPeer::onChangeRootDisplayed( sal_Bool bIsRootDisplayed ) 1468 { 1469 if( mbIsRootDisplayed == bIsRootDisplayed ) 1470 return; 1471 1472 mbIsRootDisplayed = bIsRootDisplayed; 1473 1474 UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); 1475 1476 if( rTree.GetEntryCount() == 0 ) 1477 return; 1478 1479 // todo 1480 fillTree( rTree, mxDataModel ); 1481 if( mbIsRootDisplayed ) 1482 { 1483 } 1484 else 1485 { 1486 } 1487 } 1488 1489 bool TreeControlPeer::loadImage( const ::rtl::OUString& rURL, Image& rImage ) 1490 { 1491 if( !mxGraphicProvider.is() ) 1492 { 1493 static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ); 1494 Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); 1495 if( xORB.is() ) 1496 { 1497 Reference< XInterface > x( xORB->createInstance( aSN ) ); 1498 mxGraphicProvider.query( x ); 1499 mxGraphicProvider = Reference< XGraphicProvider >( x, UNO_QUERY ); 1500 } 1501 } 1502 1503 if( mxGraphicProvider.is() ) try 1504 { 1505 ::com::sun::star::beans::PropertyValues aProps( 1 ); 1506 aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); 1507 aProps[0].Value <<= rURL; 1508 1509 Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) ); 1510 1511 Graphic aGraphic( xGraphic ); 1512 rImage = aGraphic.GetBitmapEx(); 1513 return true; 1514 } 1515 catch( Exception& ) 1516 { 1517 } 1518 1519 return false; 1520 } 1521 1522 // ==================================================================== 1523 // class UnoTreeListBoxImpl 1524 // ==================================================================== 1525 1526 UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ) 1527 : SvTreeListBox( pParent, nWinStyle ) 1528 , mxPeer( pPeer ) 1529 { 1530 SetStyle( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL ); 1531 SetNodeDefaultImages(); 1532 SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); 1533 SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); 1534 1535 SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) ); 1536 SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) ); 1537 1538 } 1539 1540 // -------------------------------------------------------------------- 1541 1542 UnoTreeListBoxImpl::~UnoTreeListBoxImpl() 1543 { 1544 if( mxPeer.is() ) 1545 mxPeer->disposeControl(); 1546 } 1547 1548 // -------------------------------------------------------------------- 1549 1550 IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG ) 1551 { 1552 if( mxPeer.is() ) 1553 mxPeer->onSelectionChanged(); 1554 return 0; 1555 } 1556 1557 // -------------------------------------------------------------------- 1558 1559 IMPL_LINK(UnoTreeListBoxImpl, OnExpandingHdl, UnoTreeListBoxImpl*, EMPTYARG ) 1560 { 1561 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); 1562 1563 if( pEntry && mxPeer.is() ) 1564 { 1565 return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ) ? 1 : 0; 1566 } 1567 return 0; 1568 } 1569 1570 // -------------------------------------------------------------------- 1571 1572 IMPL_LINK(UnoTreeListBoxImpl, OnExpandedHdl, UnoTreeListBoxImpl*, EMPTYARG ) 1573 { 1574 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); 1575 if( pEntry && mxPeer.is() ) 1576 { 1577 mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) ); 1578 } 1579 return 0; 1580 } 1581 1582 // -------------------------------------------------------------------- 1583 1584 sal_uInt32 UnoTreeListBoxImpl::insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos ) 1585 { 1586 if( pParent ) 1587 return SvTreeListBox::Insert( pEntry, pParent, nPos ); 1588 else 1589 return SvTreeListBox::Insert( pEntry, nPos ); 1590 } 1591 1592 // -------------------------------------------------------------------- 1593 1594 void UnoTreeListBoxImpl::RequestingChilds( SvLBoxEntry* pParent ) 1595 { 1596 UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent ); 1597 if( pEntry && pEntry->mxNode.is() && mxPeer.is() ) 1598 mxPeer->onRequestChildNodes( pEntry->mxNode ); 1599 } 1600 1601 // -------------------------------------------------------------------- 1602 1603 sal_Bool UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& ) 1604 { 1605 return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false; 1606 } 1607 1608 // -------------------------------------------------------------------- 1609 1610 sal_Bool UnoTreeListBoxImpl::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ) 1611 { 1612 return mxPeer.is() ? mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ) : false; 1613 } 1614 1615 // ==================================================================== 1616 // class UnoTreeListItem 1617 // ==================================================================== 1618 1619 UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry ) 1620 : SvLBoxItem( pEntry, 0 ) 1621 { 1622 } 1623 1624 // -------------------------------------------------------------------- 1625 1626 UnoTreeListItem::UnoTreeListItem() 1627 : SvLBoxItem() 1628 { 1629 } 1630 1631 // -------------------------------------------------------------------- 1632 1633 UnoTreeListItem::~UnoTreeListItem() 1634 { 1635 } 1636 1637 // -------------------------------------------------------------------- 1638 1639 sal_uInt16 UnoTreeListItem::IsA() 1640 { 1641 return 0; 1642 } 1643 1644 // -------------------------------------------------------------------- 1645 1646 void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */, SvLBoxEntry* _pEntry) 1647 { 1648 Point aPos( rPos ); 1649 if( _pEntry ) 1650 { 1651 Size aSize( GetSize(&rDev,_pEntry) ); 1652 if( !!maImage ) 1653 { 1654 rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE ); 1655 int nWidth = maImage.GetSizePixel().Width() + 6; 1656 aPos.X() += nWidth; 1657 aSize.Width() -= nWidth; 1658 } 1659 rDev.DrawText( Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE ); 1660 } 1661 else 1662 { 1663 if( !!maImage ) 1664 { 1665 rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE); 1666 aPos.X() += maImage.GetSizePixel().Width() + 6; 1667 } 1668 rDev.DrawText( aPos, maText); 1669 } 1670 } 1671 1672 // -------------------------------------------------------------------- 1673 1674 SvLBoxItem* UnoTreeListItem::Create() const 1675 { 1676 return new UnoTreeListItem; 1677 } 1678 1679 // -------------------------------------------------------------------- 1680 1681 void UnoTreeListItem::Clone( SvLBoxItem* pSource ) 1682 { 1683 UnoTreeListItem* pSourceItem = dynamic_cast< UnoTreeListItem* >( pSource ); 1684 if( pSourceItem ) 1685 { 1686 maText = pSourceItem->maText; 1687 maImage = pSourceItem->maImage; 1688 } 1689 } 1690 1691 // -------------------------------------------------------------------- 1692 1693 OUString UnoTreeListItem::GetText() const 1694 { 1695 return maText; 1696 } 1697 1698 // -------------------------------------------------------------------- 1699 1700 void UnoTreeListItem::SetText( const OUString& rText ) 1701 { 1702 maText = rText; 1703 } 1704 1705 // -------------------------------------------------------------------- 1706 1707 void UnoTreeListItem::SetImage( const Image& rImage ) 1708 { 1709 maImage = rImage; 1710 } 1711 1712 // -------------------------------------------------------------------- 1713 1714 OUString UnoTreeListItem::GetGraphicURL() const 1715 { 1716 return maGraphicURL; 1717 } 1718 1719 // -------------------------------------------------------------------- 1720 1721 void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL ) 1722 { 1723 maGraphicURL = rGraphicURL; 1724 } 1725 1726 // -------------------------------------------------------------------- 1727 1728 void UnoTreeListItem::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData) 1729 { 1730 if( !pViewData ) 1731 pViewData = pView->GetViewDataItem( pEntry, this ); 1732 1733 pViewData->aSize = maImage.GetSizePixel(); 1734 1735 const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight()); 1736 if( pViewData->aSize.Width() ) 1737 { 1738 pViewData->aSize.Width() += 6 + aTextSize.Width(); 1739 if( pViewData->aSize.Height() < aTextSize.Height() ) 1740 pViewData->aSize.Height() = aTextSize.Height(); 1741 } 1742 else 1743 { 1744 pViewData->aSize = aTextSize; 1745 } 1746 } 1747 1748 // -------------------------------------------------------------------- 1749 1750 UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ) 1751 : SvLBoxEntry() 1752 , mxNode( xNode ) 1753 , mpPeer( pPeer ) 1754 { 1755 if( mpPeer ) 1756 mpPeer->addEntry( this ); 1757 } 1758 1759 // -------------------------------------------------------------------- 1760 1761 UnoTreeListEntry::~UnoTreeListEntry() 1762 { 1763 if( mpPeer ) 1764 mpPeer->removeEntry( this ); 1765 } 1766