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