xref: /trunk/main/svtools/source/uno/treecontrolpeer.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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