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:
LockGuardLockGuard61 LockGuard( sal_Int32& rLock )
62 : mrLock( rLock )
63 {
64 rLock++;
65 }
66
~LockGuardLockGuard67 ~LockGuard()
68 {
69 mrLock--;
70 }
71
72 sal_Int32& mrLock;
73 };
74
75 // --------------------------------------------------------------------
76
77 class ImplGraphicItem : public SvLBoxBmp
78 {
79 public:
ImplGraphicItem(SvLBoxEntry * pEntry,sal_uInt16 nFlags,Image & aImage)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:
ImplContextGraphicItem(SvLBoxEntry * pEntry,sal_uInt16 nFlags,Image & rI1,Image & rI2,sal_uInt16 nEntryFlagsBmp1)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
TreeControlPeer()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
~TreeControlPeer()178 TreeControlPeer::~TreeControlPeer()
179 {
180 if( mpTreeImpl )
181 mpTreeImpl->Clear();
182 delete mpTreeNodeMap;
183 }
184
185 // --------------------------------------------------------------------
186
addEntry(UnoTreeListEntry * pEntry)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
removeEntry(UnoTreeListEntry * pEntry)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
getEntry(const Reference<XTreeNode> & xNode,bool bThrow)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
createVclControl(Window * pParent,sal_Int64 nWinStyle)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 */
disposeControl()242 void TreeControlPeer::disposeControl()
243 {
244 delete mpTreeNodeMap;
245 mpTreeNodeMap = 0;
246 mpTreeImpl = 0;
247 }
248
249 // --------------------------------------------------------------------
250
SetWindow(Window * pWindow)251 void TreeControlPeer::SetWindow( Window* pWindow )
252 {
253 VCLXWindow::SetWindow( pWindow );
254 }
255
256 // --------------------------------------------------------------------
257
createEntry(const Reference<XTreeNode> & xNode,UnoTreeListEntry * pParent,sal_uLong nPos)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
updateEntry(UnoTreeListEntry * pEntry)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
onSelectionChanged()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
onRequestChildNodes(const Reference<XTreeNode> & xNode)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
onExpanding(const Reference<XTreeNode> & xNode,bool bExpanding)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
onExpanded(const Reference<XTreeNode> & xNode,bool bExpanding)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
fillTree(UnoTreeListBoxImpl & rTree,const Reference<XTreeDataModel> & xDataModel)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
addNode(UnoTreeListBoxImpl & rTree,const Reference<XTreeNode> & xNode,UnoTreeListEntry * pParentEntry)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
getTreeListBoxOrThrow() const474 UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException )
475 {
476 if( !mpTreeImpl )
477 throw DisposedException();
478 return *mpTreeImpl;
479 }
480
481 // --------------------------------------------------------------------
482
ChangeNodesSelection(const Any & rSelection,bool bSelect,bool bSetSelection)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
select(const Any & rSelection)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
getSelection()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
addSelectionChangeListener(const Reference<XSelectionChangeListener> & xListener)590 void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
591 {
592 maSelectionListeners.addInterface( xListener );
593 }
594
595 // -------------------------------------------------------------------
596
removeSelectionChangeListener(const Reference<XSelectionChangeListener> & xListener)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
addSelection(const Any & rSelection)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
removeSelection(const Any & rSelection)614 void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
615 {
616 ChangeNodesSelection( rSelection, false, false );
617 }
618
619 // -------------------------------------------------------------------
620
clearSelection()621 void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException)
622 {
623 ::vos::OGuard aGuard( GetMutex() );
624 getTreeListBoxOrThrow().SelectAll( sal_False );
625 }
626
627 // -------------------------------------------------------------------
628
getSelectionCount()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
TreeSelectionEnumeration(std::list<Any> & rSelection)650 TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection )
651 {
652 maSelection.swap( rSelection );
653 maIter = maSelection.begin();
654 }
655
656 // -------------------------------------------------------------------
657
hasMoreElements()658 ::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException)
659 {
660 return maIter != maSelection.end();
661 }
662
663 // -------------------------------------------------------------------
664
nextElement()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
createSelectionEnumeration()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
createReverseSelectionEnumeration()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
getDefaultExpandedGraphicURL()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
setDefaultExpandedGraphicURL(const::rtl::OUString & sDefaultExpandedGraphicURL)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
getDefaultCollapsedGraphicURL()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
setDefaultCollapsedGraphicURL(const::rtl::OUString & sDefaultCollapsedGraphicURL)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
isNodeExpanded(const Reference<XTreeNode> & xNode)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
isNodeCollapsed(const Reference<XTreeNode> & xNode)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
makeNodeVisible(const Reference<XTreeNode> & xNode)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
isNodeVisible(const Reference<XTreeNode> & xNode)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
expandNode(const Reference<XTreeNode> & xNode)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
collapseNode(const Reference<XTreeNode> & xNode)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
addTreeExpansionListener(const Reference<XTreeExpansionListener> & xListener)867 void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
868 {
869 maTreeExpansionListeners.addInterface( xListener );
870 }
871
872 // -------------------------------------------------------------------
873
removeTreeExpansionListener(const Reference<XTreeExpansionListener> & xListener)874 void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
875 {
876 maTreeExpansionListeners.removeInterface( xListener );
877 }
878
879 // -------------------------------------------------------------------
880
getNodeForLocation(sal_Int32 x,sal_Int32 y)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
getClosestNodeForLocation(sal_Int32 x,sal_Int32 y)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
getNodeRect(const Reference<XTreeNode> & i_Node)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
isEditing()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
stopEditing()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
cancelEditing()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
startEditingAtNode(const Reference<XTreeNode> & xNode)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
addTreeEditListener(const Reference<XTreeEditListener> & xListener)977 void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
978 {
979 maTreeEditListeners.addInterface( xListener );
980 }
981
removeTreeEditListener(const Reference<XTreeEditListener> & xListener)982 void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
983 {
984 maTreeEditListeners.removeInterface( xListener );
985 }
986
onEditingEntry(UnoTreeListEntry * pEntry)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
onEditedEntry(UnoTreeListEntry * pEntry,const XubString & rNewText)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
treeNodesChanged(const::com::sun::star::awt::tree::TreeDataModelEvent & rEvent)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
treeNodesInserted(const::com::sun::star::awt::tree::TreeDataModelEvent & rEvent)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
treeNodesRemoved(const::com::sun::star::awt::tree::TreeDataModelEvent & rEvent)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
treeStructureChanged(const::com::sun::star::awt::tree::TreeDataModelEvent & rEvent)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
updateTree(const::com::sun::star::awt::tree::TreeDataModelEvent & rEvent,bool bRecursive)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
updateNode(UnoTreeListBoxImpl & rTree,const Reference<XTreeNode> & xNode,bool bRecursive)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
updateChildNodes(UnoTreeListBoxImpl & rTree,const Reference<XTreeNode> & xParentNode,UnoTreeListEntry * pParentEntry)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
getEntryString(const Any & rValue)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
disposing(const::com::sun::star::lang::EventObject &)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
onChangeDataModel(UnoTreeListBoxImpl & rTree,const Reference<XTreeDataModel> & xDataModel)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
getMinimumSize()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
getPreferredSize()1291 ::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException)
1292 {
1293 return getMinimumSize();
1294 }
1295
calcAdjustedSize(const::com::sun::star::awt::Size & rNewSize)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
setProperty(const::rtl::OUString & PropertyName,const Any & aValue)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
getProperty(const::rtl::OUString & PropertyName)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
onChangeRootDisplayed(sal_Bool bIsRootDisplayed)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
loadImage(const::rtl::OUString & rURL,Image & rImage)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
UnoTreeListBoxImpl(TreeControlPeer * pPeer,Window * pParent,WinBits nWinStyle)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
~UnoTreeListBoxImpl()1538 UnoTreeListBoxImpl::~UnoTreeListBoxImpl()
1539 {
1540 if( mxPeer.is() )
1541 mxPeer->disposeControl();
1542 }
1543
1544 // --------------------------------------------------------------------
1545
IMPL_LINK(UnoTreeListBoxImpl,OnSelectionChangeHdl,UnoTreeListBoxImpl *,EMPTYARG)1546 IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG )
1547 {
1548 if( mxPeer.is() )
1549 mxPeer->onSelectionChanged();
1550 return 0;
1551 }
1552
1553 // --------------------------------------------------------------------
1554
IMPL_LINK(UnoTreeListBoxImpl,OnExpandingHdl,UnoTreeListBoxImpl *,EMPTYARG)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
IMPL_LINK(UnoTreeListBoxImpl,OnExpandedHdl,UnoTreeListBoxImpl *,EMPTYARG)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
insert(SvLBoxEntry * pEntry,SvLBoxEntry * pParent,sal_uLong nPos)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
RequestingChilds(SvLBoxEntry * pParent)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
EditingEntry(SvLBoxEntry * pEntry,Selection &)1599 sal_Bool UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& )
1600 {
1601 return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false;
1602 }
1603
1604 // --------------------------------------------------------------------
1605
EditedEntry(SvLBoxEntry * pEntry,const XubString & rNewText)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
UnoTreeListItem(SvLBoxEntry * pEntry)1615 UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry )
1616 : SvLBoxItem( pEntry, 0 )
1617 {
1618 }
1619
1620 // --------------------------------------------------------------------
1621
UnoTreeListItem()1622 UnoTreeListItem::UnoTreeListItem()
1623 : SvLBoxItem()
1624 {
1625 }
1626
1627 // --------------------------------------------------------------------
1628
~UnoTreeListItem()1629 UnoTreeListItem::~UnoTreeListItem()
1630 {
1631 }
1632
1633 // --------------------------------------------------------------------
1634
IsA()1635 sal_uInt16 UnoTreeListItem::IsA()
1636 {
1637 return SV_ITEM_ID_LBOXSTRING;
1638 }
1639
1640 // --------------------------------------------------------------------
1641
Paint(const Point & rPos,SvLBox & rDev,sal_uInt16,SvLBoxEntry * _pEntry)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
Create() const1670 SvLBoxItem* UnoTreeListItem::Create() const
1671 {
1672 return new UnoTreeListItem;
1673 }
1674
1675 // --------------------------------------------------------------------
1676
Clone(SvLBoxItem * pSource)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
GetText() const1689 OUString UnoTreeListItem::GetText() const
1690 {
1691 return maText;
1692 }
1693
1694 // --------------------------------------------------------------------
1695
SetText(const OUString & rText)1696 void UnoTreeListItem::SetText( const OUString& rText )
1697 {
1698 maText = rText;
1699 }
1700
1701 // --------------------------------------------------------------------
1702
SetImage(const Image & rImage)1703 void UnoTreeListItem::SetImage( const Image& rImage )
1704 {
1705 maImage = rImage;
1706 }
1707
1708 // --------------------------------------------------------------------
1709
GetGraphicURL() const1710 OUString UnoTreeListItem::GetGraphicURL() const
1711 {
1712 return maGraphicURL;
1713 }
1714
1715 // --------------------------------------------------------------------
1716
SetGraphicURL(const OUString & rGraphicURL)1717 void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL )
1718 {
1719 maGraphicURL = rGraphicURL;
1720 }
1721
1722 // --------------------------------------------------------------------
1723
InitViewData(SvLBox * pView,SvLBoxEntry * pEntry,SvViewDataItem * pViewData)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
UnoTreeListEntry(const Reference<XTreeNode> & xNode,TreeControlPeer * pPeer)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
~UnoTreeListEntry()1757 UnoTreeListEntry::~UnoTreeListEntry()
1758 {
1759 if( mpPeer )
1760 mpPeer->removeEntry( this );
1761 }
1762