| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svtools.hxx" |
| |
| #define _SVTREEBX_CXX |
| #include <tools/debug.hxx> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/view/SelectionType.hpp> |
| #include <toolkit/helper/property.hxx> |
| #include <toolkit/helper/vclunohelper.hxx> |
| |
| #include <com/sun/star/awt/tree/XMutableTreeNode.hpp> |
| #include <treecontrolpeer.hxx> |
| #include <comphelper/processfactory.hxx> |
| |
| #include <rtl/ref.hxx> |
| #include <vcl/graph.hxx> |
| #include <svtools/svtreebx.hxx> |
| |
| #include <map> |
| |
| using ::rtl::OUString; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::awt::tree; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::view; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::graphic; |
| |
| #define O(x) OUString( RTL_CONSTASCII_USTRINGPARAM(x) ) |
| |
| struct LockGuard |
| { |
| public: |
| LockGuard( sal_Int32& rLock ) |
| : mrLock( rLock ) |
| { |
| rLock++; |
| } |
| |
| ~LockGuard() |
| { |
| mrLock--; |
| } |
| |
| sal_Int32& mrLock; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class ImplGraphicItem : public SvLBoxBmp |
| { |
| public: |
| ImplGraphicItem( SvLBoxEntry* pEntry, sal_uInt16 nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {} |
| |
| OUString msGraphicURL; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class ImplContextGraphicItem : public SvLBoxContextBmp |
| { |
| public: |
| ImplContextGraphicItem( SvLBoxEntry* pEntry,sal_uInt16 nFlags,Image& rI1,Image& rI2, sal_uInt16 nEntryFlagsBmp1) |
| : SvLBoxContextBmp( pEntry, nFlags, rI1, rI2, nEntryFlagsBmp1 ) {} |
| |
| OUString msExpandedGraphicURL; |
| OUString msCollapsedGraphicURL; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class UnoTreeListBoxImpl : public SvTreeListBox |
| { |
| public: |
| UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ); |
| ~UnoTreeListBoxImpl(); |
| |
| sal_uInt32 insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos=LIST_APPEND ); |
| |
| virtual void RequestingChilds( SvLBoxEntry* pParent ); |
| |
| virtual sal_Bool EditingEntry( SvLBoxEntry* pEntry, Selection& ); |
| virtual sal_Bool EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ); |
| |
| DECL_LINK( OnSelectionChangeHdl, UnoTreeListBoxImpl* ); |
| DECL_LINK( OnExpandingHdl, UnoTreeListBoxImpl* ); |
| DECL_LINK( OnExpandedHdl, UnoTreeListBoxImpl* ); |
| |
| private: |
| rtl::Reference< TreeControlPeer > mxPeer; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class SVT_DLLPUBLIC UnoTreeListItem : public SvLBoxItem |
| { |
| public: |
| UnoTreeListItem( SvLBoxEntry* ); |
| UnoTreeListItem(); |
| virtual ~UnoTreeListItem(); |
| virtual sal_uInt16 IsA(); |
| void InitViewData( SvLBox*,SvLBoxEntry*,SvViewDataItem* ); |
| OUString GetText() const; |
| void SetText( const OUString& rText ); |
| Image GetImage() const; |
| void SetImage( const Image& rImage ); |
| OUString GetGraphicURL() const; |
| void SetGraphicURL( const OUString& rGraphicURL ); |
| void Paint( const Point&, SvLBox& rDev, sal_uInt16 nFlags,SvLBoxEntry* ); |
| SvLBoxItem* Create() const; |
| void Clone( SvLBoxItem* pSource ); |
| |
| private: |
| OUString maText; |
| OUString maGraphicURL; |
| Image maImage; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class UnoTreeListEntry : public SvLBoxEntry |
| { |
| public: |
| UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ); |
| virtual ~UnoTreeListEntry(); |
| |
| Reference< XTreeNode > mxNode; |
| TreeControlPeer* mpPeer; |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| class TreeNodeMap : public std::map< Reference< XTreeNode >, UnoTreeListEntry* > |
| { |
| }; |
| |
| // -------------------------------------------------------------------- |
| |
| TreeControlPeer::TreeControlPeer() |
| : maSelectionListeners( *this ) |
| , maTreeExpansionListeners( *this ) |
| , maTreeEditListeners( *this ) |
| , mpTreeImpl( 0 ) |
| , mnEditLock( 0 ) |
| , mpTreeNodeMap( 0 ) |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| TreeControlPeer::~TreeControlPeer() |
| { |
| if( mpTreeImpl ) |
| mpTreeImpl->Clear(); |
| delete mpTreeNodeMap; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry ) |
| { |
| if( pEntry && pEntry->mxNode.is() ) |
| { |
| if( !mpTreeNodeMap ) |
| { |
| mpTreeNodeMap = new TreeNodeMap(); |
| } |
| |
| (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::removeEntry( UnoTreeListEntry* pEntry ) |
| { |
| if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() ) |
| { |
| TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) ); |
| if( aIter != mpTreeNodeMap->end() ) |
| { |
| mpTreeNodeMap->erase( aIter ); |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) throw( IllegalArgumentException ) |
| { |
| if( mpTreeNodeMap ) |
| { |
| TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) ); |
| if( aIter != mpTreeNodeMap->end() ) |
| return (*aIter).second; |
| } |
| |
| if( bThrow ) |
| throw IllegalArgumentException(); |
| |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| Window* TreeControlPeer::createVclControl( Window* pParent, sal_Int64 nWinStyle ) |
| { |
| mpTreeImpl = new UnoTreeListBoxImpl( this, pParent, nWinStyle ); |
| return mpTreeImpl; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| /** called from the UnoTreeListBoxImpl when it gets deleted */ |
| void TreeControlPeer::disposeControl() |
| { |
| delete mpTreeNodeMap; |
| mpTreeNodeMap = 0; |
| mpTreeImpl = 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::SetWindow( Window* pWindow ) |
| { |
| VCLXWindow::SetWindow( pWindow ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, sal_uLong nPos /* = LIST_APPEND */ ) |
| { |
| UnoTreeListEntry* pEntry = 0; |
| if( mpTreeImpl ) |
| { |
| Image aImage; |
| pEntry = new UnoTreeListEntry( xNode, this ); |
| ImplContextGraphicItem* pContextBmp= new ImplContextGraphicItem( pEntry,0, aImage, aImage, SVLISTENTRYFLAG_EXPANDED ); |
| |
| pEntry->AddItem( pContextBmp ); |
| |
| UnoTreeListItem * pUnoItem = new UnoTreeListItem( pEntry ); |
| |
| if( xNode->getNodeGraphicURL().getLength() ) |
| { |
| pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() ); |
| Image aNodeImage; |
| loadImage( xNode->getNodeGraphicURL(), aNodeImage ); |
| pUnoItem->SetImage( aNodeImage ); |
| mpTreeImpl->AdjustEntryHeight( aNodeImage ); |
| } |
| |
| pEntry->AddItem( pUnoItem ); |
| |
| mpTreeImpl->insert( pEntry, pParent, nPos ); |
| |
| if( msDefaultExpandedGraphicURL.getLength() ) |
| mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); |
| |
| if( msDefaultCollapsedGraphicURL.getLength() ) |
| mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); |
| |
| updateEntry( pEntry ); |
| } |
| return pEntry; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| bool TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry ) |
| { |
| bool bChanged = false; |
| if( pEntry && pEntry->mxNode.is() && mpTreeImpl ) |
| { |
| const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) ); |
| UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( pEntry->GetItem( 1 ) ); |
| if( pUnoItem ) |
| { |
| if( aValue != pUnoItem->GetText() ) |
| { |
| pUnoItem->SetText( aValue ); |
| bChanged = true; |
| } |
| |
| if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() ) |
| { |
| Image aImage; |
| if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) ) |
| { |
| pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() ); |
| pUnoItem->SetImage( aImage ); |
| mpTreeImpl->AdjustEntryHeight( aImage ); |
| bChanged = true; |
| } |
| } |
| } |
| |
| if( (pEntry->mxNode->hasChildrenOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == sal_True) ) |
| { |
| pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildrenOnDemand() ? sal_True : sal_False ); |
| bChanged = true; |
| } |
| |
| ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); |
| if( pContextGraphicItem ) |
| { |
| if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() ) |
| { |
| Image aImage; |
| if( loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) ) |
| { |
| pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL(); |
| mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage ); |
| bChanged = true; |
| } |
| } |
| if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() ) |
| { |
| Image aImage; |
| if( loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) ) |
| { |
| pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL(); |
| mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage ); |
| bChanged = true; |
| } |
| } |
| } |
| |
| if( bChanged ) |
| mpTreeImpl->GetModel()->InvalidateEntry( pEntry ); |
| } |
| |
| return bChanged; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::onSelectionChanged() |
| { |
| Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); |
| EventObject aEvent( xSource ); |
| maSelectionListeners.selectionChanged( aEvent ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode ) |
| { |
| try |
| { |
| Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); |
| TreeExpansionEvent aEvent( xSource, xNode ); |
| maTreeExpansionListeners.requestChildNodes( aEvent ); |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding ) |
| { |
| try |
| { |
| Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); |
| TreeExpansionEvent aEvent( xSource, xNode ); |
| if( bExpanding ) |
| { |
| maTreeExpansionListeners.treeExpanding( aEvent ); |
| } |
| else |
| { |
| maTreeExpansionListeners.treeCollapsing( aEvent ); |
| } |
| } |
| catch( Exception& ) |
| { |
| return false; |
| } |
| return true; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding ) |
| { |
| try |
| { |
| Reference< XInterface > xSource( static_cast< ::cppu::OWeakObject* >( this ) ); |
| TreeExpansionEvent aEvent( xSource, xNode ); |
| |
| if( bExpanding ) |
| { |
| maTreeExpansionListeners.treeExpanded( aEvent ); |
| } |
| else |
| { |
| maTreeExpansionListeners.treeCollapsed( aEvent ); |
| } |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) |
| { |
| rTree.Clear(); |
| |
| if( xDataModel.is() ) |
| { |
| Reference< XTreeNode > xRootNode( xDataModel->getRoot() ); |
| if( xRootNode.is() ) |
| { |
| if( mbIsRootDisplayed ) |
| { |
| addNode( rTree, xRootNode, 0 ); |
| } |
| else |
| { |
| const sal_Int32 nChildCount = xRootNode->getChildCount(); |
| for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
| addNode( rTree, xRootNode->getChildAt( nChild ), 0 ); |
| } |
| } |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry ) |
| { |
| if( xNode.is() ) |
| { |
| UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, LIST_APPEND ); |
| const sal_Int32 nChildCount = xNode->getChildCount(); |
| for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
| addNode( rTree, xNode->getChildAt( nChild ), pEntry ); |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const throw (RuntimeException ) |
| { |
| if( !mpTreeImpl ) |
| throw DisposedException(); |
| return *mpTreeImpl; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) throw( RuntimeException, IllegalArgumentException ) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| Reference< XTreeNode > xTempNode; |
| Sequence< XTreeNode > aTempSeq; |
| |
| const Reference< XTreeNode > *pNodes = 0; |
| sal_Int32 nCount = 0; |
| |
| if( rSelection.hasValue() ) |
| { |
| switch( rSelection.getValueTypeClass() ) |
| { |
| case TypeClass_INTERFACE: |
| { |
| rSelection >>= xTempNode; |
| if( xTempNode.is() ) |
| { |
| nCount = 1; |
| pNodes = &xTempNode; |
| } |
| break; |
| } |
| case TypeClass_SEQUENCE: |
| { |
| if( rSelection.getValueType() == ::getCppuType( (const Sequence< Reference< XTreeNode > > *) 0 ) ) |
| { |
| const Sequence< Reference< XTreeNode > >& rSeq( *(const Sequence< Reference< XTreeNode > > *)rSelection.getValue() ); |
| nCount = rSeq.getLength(); |
| if( nCount ) |
| pNodes = rSeq.getConstArray(); |
| } |
| break; |
| } |
| default: |
| break; |
| } |
| |
| if( nCount == 0 ) |
| throw IllegalArgumentException(); |
| } |
| |
| if( bSetSelection ) |
| rTree.SelectAll( sal_False ); |
| |
| if( pNodes && nCount ) |
| { |
| while( nCount-- ) |
| { |
| UnoTreeListEntry* pEntry = getEntry( *pNodes++ ); |
| rTree.Select( pEntry, bSelect ? sal_True : sal_False ); |
| } |
| } |
| } |
| |
| // ------------------------------------------------------------------- |
| // ::com::sun::star::view::XSelectionSupplier |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| ChangeNodesSelection( rSelection, true, true ); |
| return sal_True; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Any SAL_CALL TreeControlPeer::getSelection() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| Any aRet; |
| |
| sal_uLong nSelectionCount = rTree.GetSelectionCount(); |
| if( nSelectionCount == 1 ) |
| { |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
| if( pEntry && pEntry->mxNode.is() ) |
| aRet <<= pEntry->mxNode; |
| } |
| else if( nSelectionCount > 1 ) |
| { |
| Sequence< Reference< XTreeNode > > aSelection( nSelectionCount ); |
| Reference< XTreeNode >* pNodes = aSelection.getArray(); |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
| while( pEntry && nSelectionCount ) |
| { |
| *pNodes++ = pEntry->mxNode; |
| pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
| --nSelectionCount; |
| } |
| |
| OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); |
| aRet <<= aSelection; |
| } |
| |
| return aRet; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) |
| { |
| maSelectionListeners.addInterface( xListener ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException) |
| { |
| maSelectionListeners.addInterface( xListener ); |
| } |
| |
| // ------------------------------------------------------------------- |
| // ::com::sun::star::view::XMultiSelectionSupplier |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ChangeNodesSelection( rSelection, true, false ); |
| return sal_True; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ChangeNodesSelection( rSelection, false, false ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::clearSelection() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| getTreeListBoxOrThrow().SelectAll( sal_False ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| return getTreeListBoxOrThrow().GetSelectionCount(); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| class TreeSelectionEnumeration : public ::cppu::WeakImplHelper1< XEnumeration > |
| { |
| public: |
| TreeSelectionEnumeration( std::list< Any >& rSelection ); |
| virtual ::sal_Bool SAL_CALL hasMoreElements() throw (RuntimeException); |
| virtual Any SAL_CALL nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException); |
| |
| std::list< Any > maSelection; |
| std::list< Any >::iterator maIter; |
| }; |
| |
| // ------------------------------------------------------------------- |
| |
| TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection ) |
| { |
| maSelection.swap( rSelection ); |
| maIter = maSelection.begin(); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| ::sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() throw (RuntimeException) |
| { |
| return maIter != maSelection.end(); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Any SAL_CALL TreeSelectionEnumeration::nextElement() throw (NoSuchElementException, WrappedTargetException, RuntimeException) |
| { |
| if( maIter == maSelection.end() ) |
| throw NoSuchElementException(); |
| |
| return (*maIter++); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); |
| std::list< Any > aSelection( nSelectionCount ); |
| |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
| while( pEntry && nSelectionCount ) |
| { |
| aSelection.push_back( Any( pEntry->mxNode ) ); |
| pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
| --nSelectionCount; |
| } |
| |
| OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); |
| |
| return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); |
| std::list< Any > aSelection; |
| |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
| while( pEntry && nSelectionCount ) |
| { |
| aSelection.push_front( Any( pEntry->mxNode ) ); |
| pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
| --nSelectionCount; |
| } |
| |
| OSL_ASSERT( (pEntry == 0) && (nSelectionCount == 0) ); |
| |
| return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); |
| } |
| |
| // -------------------------------------------------------------------- |
| // ::com::sun::star::awt::XTreeControl |
| // -------------------------------------------------------------------- |
| |
| OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| return msDefaultExpandedGraphicURL; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const ::rtl::OUString& sDefaultExpandedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| if( msDefaultExpandedGraphicURL != sDefaultExpandedGraphicURL ) |
| { |
| if( sDefaultExpandedGraphicURL.getLength() ) |
| loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage ); |
| else |
| maDefaultExpandedImage = Image(); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| SvLBoxEntry* pEntry = rTree.First(); |
| while( pEntry ) |
| { |
| ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); |
| if( pContextGraphicItem ) |
| { |
| if( pContextGraphicItem->msExpandedGraphicURL.getLength() == 0 ) |
| rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); |
| } |
| pEntry = rTree.Next( pEntry ); |
| } |
| |
| msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| return msDefaultCollapsedGraphicURL; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const ::rtl::OUString& sDefaultCollapsedGraphicURL ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| if( msDefaultCollapsedGraphicURL != sDefaultCollapsedGraphicURL ) |
| { |
| if( sDefaultCollapsedGraphicURL.getLength() ) |
| loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage ); |
| else |
| maDefaultCollapsedImage = Image(); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| SvLBoxEntry* pEntry = rTree.First(); |
| while( pEntry ) |
| { |
| ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( pEntry->GetItem( 0 ) ); |
| if( pContextGraphicItem ) |
| { |
| if( pContextGraphicItem->msCollapsedGraphicURL.getLength() == 0 ) |
| rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); |
| } |
| pEntry = rTree.Next( pEntry ); |
| } |
| |
| msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| return ( pEntry && rTree.IsExpanded( pEntry ) ) ? sal_True : sal_False; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| return !isNodeExpanded( xNode ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| if( pEntry ) |
| rTree.MakeVisible( pEntry ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| return ( pEntry && rTree.IsEntryVisible( pEntry ) ) ? sal_True : sal_False; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| if( pEntry ) |
| rTree.Expand( pEntry ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| if( pEntry ) |
| rTree.Collapse( pEntry ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) |
| { |
| maTreeExpansionListeners.addInterface( xListener ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException) |
| { |
| maTreeExpansionListeners.removeInterface( xListener ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| Reference< XTreeNode > xNode; |
| |
| const Point aPos( x, y ); |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) ); |
| if( pEntry ) |
| xNode = pEntry->mxNode; |
| |
| return xNode; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| Reference< XTreeNode > xNode; |
| |
| const Point aPos( x, y ); |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, sal_True ) ); |
| if( pEntry ) |
| xNode = pEntry->mxNode; |
| |
| return xNode; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( i_Node, true ); |
| |
| ::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) ); |
| return VCLUnoHelper::ConvertToAWTRect( aEntryRect ); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::isEditing( ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| return rTree.IsEditingActive() ? sal_True : sal_False; |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL TreeControlPeer::stopEditing() throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| if( rTree.IsEditingActive() ) |
| { |
| rTree.EndEditing(sal_False); |
| return sal_True; |
| } |
| else |
| { |
| return sal_False; |
| } |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::cancelEditing( ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| rTree.EndEditing(sal_False); |
| } |
| |
| // ------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| UnoTreeListEntry* pEntry = getEntry( xNode ); |
| rTree.EditEntry( pEntry ); |
| } |
| |
| void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) |
| { |
| maTreeEditListeners.addInterface( xListener ); |
| } |
| |
| void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException) |
| { |
| maTreeEditListeners.removeInterface( xListener ); |
| } |
| |
| bool TreeControlPeer::onEditingEntry( UnoTreeListEntry* pEntry ) |
| { |
| if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0) ) |
| { |
| try |
| { |
| maTreeEditListeners.nodeEditing( pEntry->mxNode ); |
| } |
| catch( VetoException& ) |
| { |
| return false; |
| } |
| catch( Exception& ) |
| { |
| } |
| } |
| return true; |
| } |
| |
| bool TreeControlPeer::onEditedEntry( UnoTreeListEntry* pEntry, const XubString& rNewText ) |
| { |
| if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try |
| { |
| LockGuard aLockGuard( mnEditLock ); |
| const OUString aNewText( rNewText ); |
| if( maTreeEditListeners.getLength() > 0 ) |
| { |
| maTreeEditListeners.nodeEdited( pEntry->mxNode, aNewText ); |
| return false; |
| } |
| else |
| { |
| Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY ); |
| if( xMutableNode.is() ) |
| xMutableNode->setDisplayValue( Any( aNewText ) ); |
| else |
| return false; |
| } |
| |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| return true; |
| } |
| |
| // -------------------------------------------------------------------- |
| // ::com::sun::star::awt::tree::TreeDataModelListener |
| // -------------------------------------------------------------------- |
| |
| void SAL_CALL TreeControlPeer::treeNodesChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| if( mnEditLock != 0 ) |
| return; |
| |
| updateTree( rEvent, true ); |
| } |
| |
| void SAL_CALL TreeControlPeer::treeNodesInserted( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| if( mnEditLock != 0 ) |
| return; |
| |
| updateTree( rEvent, true ); |
| } |
| |
| void SAL_CALL TreeControlPeer::treeNodesRemoved( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| if( mnEditLock != 0 ) |
| return; |
| |
| updateTree( rEvent, true ); |
| } |
| |
| void SAL_CALL TreeControlPeer::treeStructureChanged( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent ) throw (RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| if( mnEditLock != 0 ) |
| return; |
| |
| updateTree( rEvent, true ); |
| } |
| |
| void TreeControlPeer::updateTree( const ::com::sun::star::awt::tree::TreeDataModelEvent& rEvent, bool bRecursive ) |
| { |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| Sequence< Reference< XTreeNode > > Nodes; |
| Reference< XTreeNode > xNode( rEvent.ParentNode ); |
| if( !xNode.is() && Nodes.getLength() ) |
| { |
| xNode = Nodes[0]; |
| } |
| |
| if( xNode.is() ) |
| updateNode( rTree, xNode, bRecursive ); |
| } |
| |
| void TreeControlPeer::updateNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, bool bRecursive ) |
| { |
| if( xNode.is() ) |
| { |
| UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); |
| |
| if( !pNodeEntry ) |
| { |
| Reference< XTreeNode > xParentNode( xNode->getParent() ); |
| UnoTreeListEntry* pParentEntry = 0; |
| sal_uLong nChild = LIST_APPEND; |
| |
| if( xParentNode.is() ) |
| { |
| pParentEntry = getEntry( xParentNode ); |
| nChild = xParentNode->getIndex( xNode ); |
| } |
| |
| pNodeEntry = createEntry( xNode, pParentEntry, nChild ); |
| } |
| |
| if( bRecursive ) |
| updateChildNodes( rTree, xNode, pNodeEntry ); |
| } |
| } |
| |
| void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry ) |
| { |
| if( xParentNode.is() && pParentEntry ) |
| { |
| UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) ); |
| |
| const sal_Int32 nChildCount = xParentNode->getChildCount(); |
| for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
| { |
| Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) ); |
| if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) ) |
| { |
| UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); |
| if( pNodeEntry == 0 ) |
| { |
| // child node is not yet part of the tree, add it |
| pCurrentChild = createEntry( xNode, pParentEntry, nChild ); |
| } |
| else if( pNodeEntry != pCurrentChild ) |
| { |
| // node is already part of the tree, but not on the correct position |
| rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild ); |
| pCurrentChild = pNodeEntry; |
| updateEntry( pCurrentChild ); |
| } |
| } |
| else |
| { |
| // child node has entry and entry is equal to current entry, |
| // so no structural changes happened |
| updateEntry( pCurrentChild ); |
| } |
| |
| pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); |
| } |
| |
| // check if we have entries without nodes left, we need to remove them |
| while( pCurrentChild ) |
| { |
| UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( rTree.NextSibling( pCurrentChild ) ); |
| rTree.GetModel()->Remove( pCurrentChild ); |
| pCurrentChild = pNextChild; |
| } |
| } |
| } |
| |
| OUString TreeControlPeer::getEntryString( const Any& rValue ) |
| { |
| OUString sValue; |
| if( rValue.hasValue() ) |
| { |
| switch( rValue.getValueTypeClass() ) |
| { |
| case TypeClass_SHORT: |
| case TypeClass_LONG: |
| { |
| sal_Int32 nValue = 0; |
| if( rValue >>= nValue ) |
| sValue = OUString::valueOf( nValue ); |
| break; |
| } |
| case TypeClass_BYTE: |
| case TypeClass_UNSIGNED_SHORT: |
| case TypeClass_UNSIGNED_LONG: |
| { |
| sal_uInt32 nValue = 0; |
| if( rValue >>= nValue ) |
| sValue = OUString::valueOf( (sal_Int64)nValue ); |
| break; |
| } |
| case TypeClass_HYPER: |
| { |
| sal_Int64 nValue = 0; |
| if( rValue >>= nValue ) |
| sValue = OUString::valueOf( nValue ); |
| break; |
| } |
| case TypeClass_UNSIGNED_HYPER: |
| { |
| sal_uInt64 nValue = 0; |
| if( rValue >>= nValue ) |
| sValue = OUString::valueOf( (sal_Int64)nValue ); |
| break; |
| } |
| case TypeClass_FLOAT: |
| case TypeClass_DOUBLE: |
| { |
| double fValue = 0.0; |
| if( rValue >>= fValue ) |
| sValue = OUString::valueOf( fValue ); |
| break; |
| } |
| case TypeClass_STRING: |
| rValue >>= sValue; |
| break; |
| /* |
| case TypeClass_INTERFACE: |
| // @todo |
| break; |
| case TypeClass_SEQUENCE: |
| { |
| Sequence< Any > aValues; |
| if( aValue >>= aValues ) |
| { |
| updateEntry( SvLBoxEntry& rEntry, aValues ); |
| return; |
| } |
| } |
| break; |
| */ |
| default: |
| break; |
| } |
| } |
| return sValue; |
| } |
| |
| // XEventListener |
| void SAL_CALL TreeControlPeer::disposing( const ::com::sun::star::lang::EventObject& ) throw(::com::sun::star::uno::RuntimeException) |
| { |
| // model is disposed, so we clear our tree |
| ::vos::OGuard aGuard( GetMutex() ); |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| rTree.Clear(); |
| mxDataModel.clear(); |
| } |
| |
| void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) |
| { |
| if( xDataModel.is() && (mxDataModel == xDataModel) ) |
| return; // do nothing |
| |
| Reference< XTreeDataModelListener > xListener( this ); |
| |
| if( mxDataModel.is() ) |
| mxDataModel->removeTreeDataModelListener( xListener ); |
| |
| if( !xDataModel.is() ) |
| { |
| static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.tree.DefaultTreeDataModel" ) ); |
| Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); |
| if( xORB.is() ) |
| { |
| mxDataModel.query( xORB->createInstance( aSN ) ); |
| } |
| } |
| |
| mxDataModel = xDataModel; |
| |
| fillTree( rTree, mxDataModel ); |
| |
| if( mxDataModel.is() ) |
| mxDataModel->addTreeDataModelListener( xListener ); |
| } |
| |
| // -------------------------------------------------------------------- |
| // ::com::sun::star::awt::XLayoutConstrains |
| // -------------------------------------------------------------------- |
| |
| ::com::sun::star::awt::Size TreeControlPeer::getMinimumSize() throw(RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| ::com::sun::star::awt::Size aSz; |
| /* todo |
| MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); |
| if ( pEdit ) |
| aSz = AWTSize(pEdit->CalcMinimumSize()); |
| */ |
| return aSz; |
| } |
| |
| ::com::sun::star::awt::Size TreeControlPeer::getPreferredSize() throw(RuntimeException) |
| { |
| return getMinimumSize(); |
| } |
| |
| ::com::sun::star::awt::Size TreeControlPeer::calcAdjustedSize( const ::com::sun::star::awt::Size& rNewSize ) throw(RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| ::com::sun::star::awt::Size aSz = rNewSize; |
| /* todo |
| MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); |
| if ( pEdit ) |
| aSz = AWTSize(pEdit->CalcAdjustedSize( VCLSize(rNewSize ))); |
| */ |
| return aSz; |
| } |
| |
| // -------------------------------------------------------------------- |
| // ::com::sun::star::awt::XVclWindowPeer |
| // -------------------------------------------------------------------- |
| |
| void TreeControlPeer::setProperty( const ::rtl::OUString& PropertyName, const Any& aValue) throw(RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| switch( GetPropertyId( PropertyName ) ) |
| { |
| case BASEPROPERTY_HIDEINACTIVESELECTION: |
| { |
| sal_Bool bEnabled = sal_False; |
| if ( aValue >>= bEnabled ) |
| { |
| WinBits nStyle = rTree.GetStyle(); |
| if ( bEnabled ) |
| nStyle |= WB_HIDESELECTION; |
| else |
| nStyle &= ~WB_HIDESELECTION; |
| rTree.SetStyle( nStyle ); |
| } |
| } |
| break; |
| |
| case BASEPROPERTY_TREE_SELECTIONTYPE: |
| { |
| SelectionType eSelectionType; |
| if( aValue >>= eSelectionType ) |
| { |
| SelectionMode eSelMode; |
| switch( eSelectionType ) |
| { |
| case SelectionType_SINGLE: eSelMode = SINGLE_SELECTION; break; |
| case SelectionType_RANGE: eSelMode = RANGE_SELECTION; break; |
| case SelectionType_MULTI: eSelMode = MULTIPLE_SELECTION; break; |
| // case SelectionType_NONE: |
| default: eSelMode = NO_SELECTION; break; |
| } |
| if( rTree.GetSelectionMode() != eSelMode ) |
| rTree.SetSelectionMode( eSelMode ); |
| } |
| break; |
| } |
| |
| case BASEPROPERTY_TREE_DATAMODEL: |
| onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) ); |
| break; |
| case BASEPROPERTY_ROW_HEIGHT: |
| { |
| sal_Int32 nHeight = 0; |
| if( aValue >>= nHeight ) |
| rTree.SetEntryHeight( (short)nHeight ); |
| break; |
| } |
| case BASEPROPERTY_TREE_EDITABLE: |
| { |
| sal_Bool bEnabled = false; |
| if( aValue >>= bEnabled ) |
| rTree.EnableInplaceEditing( bEnabled ? sal_True : sal_False ); |
| break; |
| } |
| case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: |
| break; // @todo |
| case BASEPROPERTY_TREE_ROOTDISPLAYED: |
| { |
| sal_Bool bDisplayed = false; |
| if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) ) |
| { |
| onChangeRootDisplayed(bDisplayed); |
| } |
| break; |
| } |
| case BASEPROPERTY_TREE_SHOWSHANDLES: |
| { |
| sal_Bool bEnabled = false; |
| if( aValue >>= bEnabled ) |
| { |
| WinBits nBits = rTree.GetStyle() & (~WB_HASLINES); |
| if( bEnabled ) |
| nBits |= WB_HASLINES; |
| if( nBits != rTree.GetStyle() ) |
| rTree.SetStyle( nBits ); |
| } |
| break; |
| } |
| case BASEPROPERTY_TREE_SHOWSROOTHANDLES: |
| { |
| sal_Bool bEnabled = false; |
| if( aValue >>= bEnabled ) |
| { |
| WinBits nBits = rTree.GetStyle() & (~WB_HASLINESATROOT); |
| if( bEnabled ) |
| nBits |= WB_HASLINESATROOT; |
| if( nBits != rTree.GetStyle() ) |
| rTree.SetStyle( nBits ); |
| } |
| break; |
| } |
| default: |
| VCLXWindow::setProperty( PropertyName, aValue ); |
| break; |
| } |
| } |
| |
| Any TreeControlPeer::getProperty( const ::rtl::OUString& PropertyName ) throw(RuntimeException) |
| { |
| ::vos::OGuard aGuard( GetMutex() ); |
| |
| const sal_uInt16 nPropId = GetPropertyId( PropertyName ); |
| if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) ) |
| { |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| switch(nPropId) |
| { |
| case BASEPROPERTY_HIDEINACTIVESELECTION: |
| return Any( ( rTree.GetStyle() & WB_HIDESELECTION ) != 0 ? sal_True : sal_False ); |
| |
| case BASEPROPERTY_TREE_SELECTIONTYPE: |
| { |
| SelectionType eSelectionType; |
| |
| SelectionMode eSelMode = rTree.GetSelectionMode(); |
| switch( eSelMode ) |
| { |
| case SINGLE_SELECTION: eSelectionType = SelectionType_SINGLE; break; |
| case RANGE_SELECTION: eSelectionType = SelectionType_RANGE; break; |
| case MULTIPLE_SELECTION:eSelectionType = SelectionType_MULTI; break; |
| // case NO_SELECTION: |
| default: eSelectionType = SelectionType_NONE; break; |
| } |
| return Any( eSelectionType ); |
| } |
| case BASEPROPERTY_ROW_HEIGHT: |
| return Any( (sal_Int32)rTree.GetEntryHeight() ); |
| case BASEPROPERTY_TREE_DATAMODEL: |
| return Any( mxDataModel ); |
| case BASEPROPERTY_TREE_EDITABLE: |
| return Any( rTree.IsInplaceEditingEnabled() ? sal_True : sal_False ); |
| case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: |
| return Any( sal_True ); // @todo |
| case BASEPROPERTY_TREE_ROOTDISPLAYED: |
| return Any( mbIsRootDisplayed ); |
| case BASEPROPERTY_TREE_SHOWSHANDLES: |
| return Any( (rTree.GetStyle() & WB_HASLINES) != 0 ? sal_True : sal_False ); |
| case BASEPROPERTY_TREE_SHOWSROOTHANDLES: |
| return Any( (rTree.GetStyle() & WB_HASLINESATROOT) != 0 ? sal_True : sal_False ); |
| } |
| } |
| return VCLXWindow::getProperty( PropertyName ); |
| } |
| |
| void TreeControlPeer::onChangeRootDisplayed( sal_Bool bIsRootDisplayed ) |
| { |
| if( mbIsRootDisplayed == bIsRootDisplayed ) |
| return; |
| |
| mbIsRootDisplayed = bIsRootDisplayed; |
| |
| UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
| |
| if( rTree.GetEntryCount() == 0 ) |
| return; |
| |
| // todo |
| fillTree( rTree, mxDataModel ); |
| if( mbIsRootDisplayed ) |
| { |
| } |
| else |
| { |
| } |
| } |
| |
| bool TreeControlPeer::loadImage( const ::rtl::OUString& rURL, Image& rImage ) |
| { |
| if( !mxGraphicProvider.is() ) |
| { |
| static const OUString aSN( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ); |
| Reference< XMultiServiceFactory > xORB( ::comphelper::getProcessServiceFactory() ); |
| if( xORB.is() ) |
| { |
| Reference< XInterface > x( xORB->createInstance( aSN ) ); |
| mxGraphicProvider.query( x ); |
| mxGraphicProvider = Reference< XGraphicProvider >( x, UNO_QUERY ); |
| } |
| } |
| |
| if( mxGraphicProvider.is() ) try |
| { |
| ::com::sun::star::beans::PropertyValues aProps( 1 ); |
| aProps[0].Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ); |
| aProps[0].Value <<= rURL; |
| |
| Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) ); |
| |
| Graphic aGraphic( xGraphic ); |
| rImage = aGraphic.GetBitmapEx(); |
| return true; |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| return false; |
| } |
| |
| // ==================================================================== |
| // class UnoTreeListBoxImpl |
| // ==================================================================== |
| |
| UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, Window* pParent, WinBits nWinStyle ) |
| : SvTreeListBox( pParent, nWinStyle ) |
| , mxPeer( pPeer ) |
| { |
| SetStyle( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL ); |
| SetNodeDefaultImages(); |
| SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); |
| SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); |
| |
| SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) ); |
| SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) ); |
| |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListBoxImpl::~UnoTreeListBoxImpl() |
| { |
| if( mxPeer.is() ) |
| mxPeer->disposeControl(); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| IMPL_LINK( UnoTreeListBoxImpl, OnSelectionChangeHdl, UnoTreeListBoxImpl*, EMPTYARG ) |
| { |
| if( mxPeer.is() ) |
| mxPeer->onSelectionChanged(); |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| IMPL_LINK(UnoTreeListBoxImpl, OnExpandingHdl, UnoTreeListBoxImpl*, EMPTYARG ) |
| { |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); |
| |
| if( pEntry && mxPeer.is() ) |
| { |
| return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ) ? 1 : 0; |
| } |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| IMPL_LINK(UnoTreeListBoxImpl, OnExpandedHdl, UnoTreeListBoxImpl*, EMPTYARG ) |
| { |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); |
| if( pEntry && mxPeer.is() ) |
| { |
| mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) ); |
| } |
| return 0; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_uInt32 UnoTreeListBoxImpl::insert( SvLBoxEntry* pEntry,SvLBoxEntry* pParent,sal_uLong nPos ) |
| { |
| if( pParent ) |
| return SvTreeListBox::Insert( pEntry, pParent, nPos ); |
| else |
| return SvTreeListBox::Insert( pEntry, nPos ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListBoxImpl::RequestingChilds( SvLBoxEntry* pParent ) |
| { |
| UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent ); |
| if( pEntry && pEntry->mxNode.is() && mxPeer.is() ) |
| mxPeer->onRequestChildNodes( pEntry->mxNode ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& ) |
| { |
| return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_Bool UnoTreeListBoxImpl::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText ) |
| { |
| return mxPeer.is() ? mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ) : false; |
| } |
| |
| // ==================================================================== |
| // class UnoTreeListItem |
| // ==================================================================== |
| |
| UnoTreeListItem::UnoTreeListItem( SvLBoxEntry* pEntry ) |
| : SvLBoxItem( pEntry, 0 ) |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListItem::UnoTreeListItem() |
| : SvLBoxItem() |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListItem::~UnoTreeListItem() |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| sal_uInt16 UnoTreeListItem::IsA() |
| { |
| return SV_ITEM_ID_LBOXSTRING; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, sal_uInt16 /* nFlags */, SvLBoxEntry* _pEntry) |
| { |
| Point aPos( rPos ); |
| if( _pEntry ) |
| { |
| Size aSize( GetSize(&rDev,_pEntry) ); |
| if( !!maImage ) |
| { |
| rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE ); |
| int nWidth = maImage.GetSizePixel().Width() + 6; |
| aPos.X() += nWidth; |
| aSize.Width() -= nWidth; |
| } |
| rDev.DrawText( Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? 0 : TEXT_DRAW_DISABLE ); |
| } |
| else |
| { |
| if( !!maImage ) |
| { |
| rDev.DrawImage( aPos, maImage, rDev.IsEnabled() ? 0 : IMAGE_DRAW_DISABLE); |
| aPos.X() += maImage.GetSizePixel().Width() + 6; |
| } |
| rDev.DrawText( aPos, maText); |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| SvLBoxItem* UnoTreeListItem::Create() const |
| { |
| return new UnoTreeListItem; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::Clone( SvLBoxItem* pSource ) |
| { |
| UnoTreeListItem* pSourceItem = dynamic_cast< UnoTreeListItem* >( pSource ); |
| if( pSourceItem ) |
| { |
| maText = pSourceItem->maText; |
| maImage = pSourceItem->maImage; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| OUString UnoTreeListItem::GetText() const |
| { |
| return maText; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::SetText( const OUString& rText ) |
| { |
| maText = rText; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::SetImage( const Image& rImage ) |
| { |
| maImage = rImage; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| OUString UnoTreeListItem::GetGraphicURL() const |
| { |
| return maGraphicURL; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL ) |
| { |
| maGraphicURL = rGraphicURL; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void UnoTreeListItem::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData) |
| { |
| if( !pViewData ) |
| pViewData = pView->GetViewDataItem( pEntry, this ); |
| |
| pViewData->aSize = maImage.GetSizePixel(); |
| |
| const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight()); |
| if( pViewData->aSize.Width() ) |
| { |
| pViewData->aSize.Width() += 6 + aTextSize.Width(); |
| if( pViewData->aSize.Height() < aTextSize.Height() ) |
| pViewData->aSize.Height() = aTextSize.Height(); |
| } |
| else |
| { |
| pViewData->aSize = aTextSize; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ) |
| : SvLBoxEntry() |
| , mxNode( xNode ) |
| , mpPeer( pPeer ) |
| { |
| if( mpPeer ) |
| mpPeer->addEntry( this ); |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| UnoTreeListEntry::~UnoTreeListEntry() |
| { |
| if( mpPeer ) |
| mpPeer->removeEntry( this ); |
| } |