diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-06-27 11:18:37 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2007-06-27 11:18:37 +0000 |
commit | 32cd4a92ef227bacd70be5c325a7e0d82bc90a7e (patch) | |
tree | c53fbccf09722f8d58fef322894698dbbe5c99a9 /svtools/source/uno/treecontrolpeer.cxx | |
parent | f62e57c487721301947458df77f845d15a790c79 (diff) |
INTEGRATION: CWS awttree01 (1.1.2); FILE ADDED
2007/06/22 13:46:32 cl 1.1.2.10: finaly fixed mutli selection enumeration
2007/06/22 09:43:48 cl 1.1.2.9: fixed multi selection enumeration
2007/06/20 11:01:34 cl 1.1.2.8: fixed gcc compiler warnings
2007/06/20 09:29:30 cl 1.1.2.7: in setDefaultCollapsedGraphicURL, do not check if it is not the same as the DefaultExpandedGraphicURL
2007/06/15 11:56:55 cl 1.1.2.6: do not throw exception in destructor
2007/06/07 08:41:44 cl 1.1.2.5: added support for images
2007/03/12 13:07:42 cl 1.1.2.4: fix unix build problems
2006/12/01 06:03:32 cl 1.1.2.3: implement a tree control api
2006/10/13 13:57:24 cl 1.1.2.2: added primilary awt tree control api
2006/09/28 13:54:19 cl 1.1.2.1: added primilary awt tree control api
Diffstat (limited to 'svtools/source/uno/treecontrolpeer.cxx')
-rw-r--r-- | svtools/source/uno/treecontrolpeer.cxx | 1757 |
1 files changed, 1757 insertions, 0 deletions
diff --git a/svtools/source/uno/treecontrolpeer.cxx b/svtools/source/uno/treecontrolpeer.cxx new file mode 100644 index 000000000000..cb7f5b75353c --- /dev/null +++ b/svtools/source/uno/treecontrolpeer.cxx @@ -0,0 +1,1757 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: treecontrolpeer.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: hr $ $Date: 2007-06-27 12:18:37 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svtools.hxx" + +#define _SVTREEBX_CXX + +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif + +#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_ +#include <com/sun/star/lang/XServiceInfo.hpp> +#endif + +#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_ +#include <com/sun/star/lang/DisposedException.hpp> +#endif + +#ifndef _COM_SUN_STAR_VIEW_SELECTIONTYPE_HPP_ +#include <com/sun/star/view/SelectionType.hpp> +#endif + +#ifndef _TOOLKIT_HELPER_PROPERTY_HXX_ +#include <toolkit/helper/property.hxx> +#endif + +#include <com/sun/star/awt/tree/XMutableTreeNode.hpp> + +#ifndef _TREE_CONTROL_PEER_HXX_ +#include <treecontrolpeer.hxx> +#endif +#ifndef _COMPHELPER_PROCESSFACTORY_HXX_ +#include <comphelper/processfactory.hxx> +#endif + +#include <rtl/ref.hxx> +#include <vcl/graph.hxx> +#include <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, USHORT nFlags, Image& aImage ) : SvLBoxBmp( pEntry, nFlags, aImage ) {} + + OUString msGraphicURL; +}; + +// -------------------------------------------------------------------- + +class ImplContextGraphicItem : public SvLBoxContextBmp +{ +public: + ImplContextGraphicItem( SvLBoxEntry* pEntry,USHORT nFlags,Image& rI1,Image& rI2, USHORT 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,ULONG nPos=LIST_APPEND ); + + virtual void RequestingChilds( SvLBoxEntry* pParent ); + + virtual BOOL EditingEntry( SvLBoxEntry* pEntry, Selection& ); + virtual 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 USHORT 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, USHORT 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_uInt32 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 ); + + if( msDefaultExpandedGraphicURL.getLength() ) + mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); + + if( msDefaultCollapsedGraphicURL.getLength() ) + mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); + + mpTreeImpl->insert( pEntry, pParent, nPos ); + + 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->hasChildsOnDemand() == sal_True) != (pEntry->HasChildsOnDemand() == TRUE) ) + { + pEntry->EnableChildsOnDemand( pEntry->mxNode->hasChildsOnDemand() ? TRUE : 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( FALSE ); + + if( pNodes && nCount ) + { + while( nCount-- ) + { + UnoTreeListEntry* pEntry = getEntry( *pNodes++ ); + rTree.Select( pEntry, bSelect ? TRUE : 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; + + 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( 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, 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, TRUE ) ); + if( pEntry ) + xNode = pEntry->mxNode; + + return xNode; +} + +// ------------------------------------------------------------------- + +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(FALSE); + return sal_True; + } + else + { + return sal_False; + } +} + +// ------------------------------------------------------------------- + +void SAL_CALL TreeControlPeer::cancelEditing( ) throw (RuntimeException) +{ + ::vos::OGuard aGuard( GetMutex() ); + + UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); + rTree.EndEditing(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; + 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_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_TREE_ROWHEIGHT: + { + sal_Int32 nHeight; + if( aValue >>= nHeight ) + rTree.SetEntryHeight( (short)nHeight ); + break; + } + case BASEPROPERTY_TREE_EDITABLE: + { + sal_Bool bEnabled; + if( aValue >>= bEnabled ) + rTree.EnableInplaceEditing( bEnabled ? TRUE : FALSE ); + break; + } + case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: + break; // @todo + case BASEPROPERTY_TREE_ROOTDISPLAYED: + sal_Bool bDisplayed; + if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) ) + { + onChangeRootDisplayed(bDisplayed); + } + break; + case BASEPROPERTY_TREE_SHOWSHANDLES: + { + sal_Bool bEnabled; + if( aValue >>= bEnabled ) + { + WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINES); + if( bEnabled ) + nBits |= WB_HASLINES; + if( nBits != rTree.GetWindowBits() ) + rTree.SetWindowBits( nBits ); + } + break; + } + case BASEPROPERTY_TREE_SHOWSROOTHANDLES: + { + sal_Bool bEnabled; + if( aValue >>= bEnabled ) + { + WinBits nBits = rTree.GetWindowBits() & (~WB_HASLINESATROOT); + if( bEnabled ) + nBits |= WB_HASLINESATROOT; + if( nBits != rTree.GetWindowBits() ) + rTree.SetWindowBits( 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_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_TREE_ROWHEIGHT: + 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.GetWindowBits() & WB_HASLINES) != 0 ? sal_True : sal_False ); + case BASEPROPERTY_TREE_SHOWSROOTHANDLES: + return Any( (rTree.GetWindowBits() & 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 ) +{ + SetWindowBits( 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,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 ); +} + +// -------------------------------------------------------------------- + +BOOL UnoTreeListBoxImpl::EditingEntry( SvLBoxEntry* pEntry, Selection& ) +{ + return mxPeer.is() ? mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ) : false; +} + +// -------------------------------------------------------------------- + +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() +{ +} + +// -------------------------------------------------------------------- + +USHORT UnoTreeListItem::IsA() +{ + return 0; +} + +// -------------------------------------------------------------------- + +void UnoTreeListItem::Paint( const Point& rPos, SvLBox& rDev, USHORT /* 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 ); +} |