diff options
Diffstat (limited to 'framework/source/tabwin/tabwindow.cxx')
-rw-r--r-- | framework/source/tabwin/tabwindow.cxx | 976 |
1 files changed, 976 insertions, 0 deletions
diff --git a/framework/source/tabwin/tabwindow.cxx b/framework/source/tabwin/tabwindow.cxx new file mode 100644 index 000000000000..d304de99122f --- /dev/null +++ b/framework/source/tabwin/tabwindow.cxx @@ -0,0 +1,976 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <tabwin/tabwindow.hxx> +#include <properties.h> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/WindowDescriptor.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +//_________________________________________________________________________________________________________________ +// includes of other projects +//_________________________________________________________________________________________________________________ +#include <rtl/ustrbuf.hxx> +#include <tools/urlobj.hxx> +#include <vcl/svapp.hxx> +#include <vcl/window.hxx> +#include <vcl/wrkwin.hxx> +#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ +#include <toolkit/unohlp.hxx> +#endif +#include <comphelper/sequenceashashmap.hxx> + +//_________________________________________________________________________________________________________________ +// Defines +//_________________________________________________________________________________________________________________ +// + +using namespace rtl; +using namespace com::sun::star; + +namespace framework +{ + +//***************************************************************************************************************** +// XInterface, XTypeProvider, XServiceInfo +//***************************************************************************************************************** +DEFINE_XINTERFACE_11 ( TabWindow , + ::cppu::OWeakObject , + DIRECT_INTERFACE( css::lang::XTypeProvider ), + DIRECT_INTERFACE( css::lang::XServiceInfo ), + DIRECT_INTERFACE( css::lang::XInitialization ), + DIRECT_INTERFACE( css::lang::XComponent ), + DIRECT_INTERFACE( css::awt::XWindowListener ), + DIRECT_INTERFACE( css::awt::XTopWindowListener ), + DIRECT_INTERFACE( css::awt::XSimpleTabController ), + DERIVED_INTERFACE( css::lang::XEventListener, css::awt::XWindowListener ), + DIRECT_INTERFACE( css::beans::XMultiPropertySet ), + DIRECT_INTERFACE( css::beans::XFastPropertySet ), + DIRECT_INTERFACE( css::beans::XPropertySet ) + ) + +DEFINE_XTYPEPROVIDER_11 ( TabWindow , + css::lang::XTypeProvider , + css::lang::XServiceInfo , + css::lang::XInitialization , + css::lang::XComponent , + css::awt::XWindowListener , + css::awt::XTopWindowListener , + css::awt::XSimpleTabController , + css::lang::XEventListener , + css::beans::XMultiPropertySet , + css::beans::XFastPropertySet , + css::beans::XPropertySet + ) + +DEFINE_XSERVICEINFO_MULTISERVICE ( TabWindow , + ::cppu::OWeakObject , + SERVICENAME_TABWINDOW , + IMPLEMENTATIONNAME_TABWINDOW + ) + +DEFINE_INIT_SERVICE ( TabWindow, {} ) + +TabWindow::TabWindow( const css::uno::Reference< css::lang::XMultiServiceFactory >& xServiceManager ) : + ThreadHelpBase( &Application::GetSolarMutex() ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , m_bInitialized( sal_False ) + , m_bDisposed( sal_False ) + , m_nNextTabID( 1 ) + , m_aTitlePropName( RTL_CONSTASCII_USTRINGPARAM( "Title" )) + , m_aPosPropName( RTL_CONSTASCII_USTRINGPARAM( "Position" )) + , m_xServiceManager( xServiceManager ) + , m_aListenerContainer( m_aLock.getShareableOslMutex() ) +{ +} + +TabWindow::~TabWindow() +{ +} + +//--------------------------------------------------------------------------------------------------------- +// Helper +//--------------------------------------------------------------------------------------------------------- + +void TabWindow::implts_LayoutWindows() const +{ + const sal_Int32 nTabControlHeight = 30; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + css::uno::Reference< css::awt::XDevice > xDevice( m_xTopWindow, css::uno::UNO_QUERY ); + css::uno::Reference< css::awt::XWindow > xWindow( m_xTopWindow, css::uno::UNO_QUERY ); + css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow ); + css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // Convert relativ size to output size. + if ( xWindow.is() && xDevice.is() ) + { + css::awt::Rectangle aRectangle = xWindow->getPosSize(); + css::awt::DeviceInfo aInfo = xDevice->getInfo(); + css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + + css::awt::Size aContainerWindowSize; + css::awt::Size aTabControlSize; + + aContainerWindowSize.Width = aSize.Width; + aTabControlSize.Width = aSize.Width; + + aContainerWindowSize.Height = std::max( sal_Int32( 0 ), aSize.Height - nTabControlHeight ); + aTabControlSize.Height = nTabControlHeight; + + xContainerWindow->setPosSize( 0, 0, + aContainerWindowSize.Width, aContainerWindowSize.Height, + css::awt::PosSize::POSSIZE ); + xTabControlWindow->setPosSize( 0, std::max( nTabControlHeight, sal_Int32( aSize.Height - nTabControlHeight)), + aTabControlSize.Width, aTabControlSize.Height, + css::awt::PosSize::POSSIZE ); + } +} + +TabControl* TabWindow::impl_GetTabControl( const css::uno::Reference< css::awt::XWindow >& rTabControlWindow ) const +{ + Window* pWindow = VCLUnoHelper::GetWindow( rTabControlWindow ); + if ( pWindow ) + return (TabControl *)pWindow; + else + return NULL; +} + +void TabWindow::impl_SetTitle( const ::rtl::OUString& rTitle ) +{ + if ( m_xTopWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( + css::uno::Reference< css::awt::XWindow >( + m_xTopWindow, css::uno::UNO_QUERY )); + if ( pWindow ) + pWindow->SetText( rTitle ); + } +} + +void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID ) const +{ + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( + ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) ); + if (pContainer!=NULL) + { + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + switch ( eNotify ) + { + case NOTIFY_INSERTED: + ((css::awt::XTabListener*)pIterator.next())->inserted( ID ); + break; + case NOTIFY_REMOVED: + ((css::awt::XTabListener*)pIterator.next())->removed( ID ); + break; + case NOTIFY_ACTIVATED: + ((css::awt::XTabListener*)pIterator.next())->activated( ID ); + break; + case NOTIFY_DEACTIVATED: + ((css::awt::XTabListener*)pIterator.next())->deactivated( ID ); + break; + default: + break; + } + } + catch( css::uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } +} + +void TabWindow::implts_SendNotification( Notification eNotify, sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& rSeq ) const +{ + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( + ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >*) NULL ) ); + if (pContainer!=NULL) + { + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + switch ( eNotify ) + { + case NOTIFY_CHANGED: + ((css::awt::XTabListener*)pIterator.next())->changed( ID, rSeq ); + break; + default: + break; + } + } + catch( css::uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// Links +//--------------------------------------------------------------------------------------------------------- + +IMPL_LINK( TabWindow, Activate, TabControl*, pTabControl ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + sal_Int32 nPageId = pTabControl->GetCurPageId(); + + rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( nPageId )); + impl_SetTitle( aTitle ); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_SendNotification( NOTIFY_ACTIVATED, nPageId ); + + return 1; +} + +IMPL_LINK( TabWindow, Deactivate, TabControl*, pTabControl ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + sal_Int32 nPageId = pTabControl->GetCurPageId(); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_SendNotification( NOTIFY_DEACTIVATED, nPageId ); + + return 1; +} + +//--------------------------------------------------------------------------------------------------------- +// XInitilization +//--------------------------------------------------------------------------------------------------------- + +void SAL_CALL TabWindow::initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) +throw (css::uno::Exception, css::uno::RuntimeException) +{ + const rtl::OUString aTopWindowArgName( RTL_CONSTASCII_USTRINGPARAM( "TopWindow" )); + const rtl::OUString aSizeArgName( RTL_CONSTASCII_USTRINGPARAM( "Size" )); + + css::awt::Size aDefaultSize( 500, 500 ); + css::awt::Size aSize( aDefaultSize ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + sal_Bool bInitalized( m_bInitialized ); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xServiceManager ); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( !bInitalized ) + { + css::beans::PropertyValue aPropValue; + css::uno::Reference< css::awt::XTopWindow > xTopWindow; + css::uno::Reference< css::awt::XToolkit > xToolkit; + css::awt::WindowDescriptor aDescriptor; + + if ( xSMGR.is() ) + { + try + { + xToolkit = css::uno::Reference< css::awt::XToolkit >( + xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY ); + } + catch ( css::uno::RuntimeException& ) + { + throw; + } + catch ( css::uno::Exception& ) + { + } + } + + for ( int i = 0; i < aArguments.getLength(); i++ ) + { + if ( aArguments[i] >>= aPropValue ) + { + if ( aPropValue.Name == aTopWindowArgName ) + aPropValue.Value >>= xTopWindow; + else if ( aPropValue.Name == aSizeArgName ) + { + aPropValue.Value >>= aSize; + if ( aSize.Width <= 0 ) + aSize.Width = aDefaultSize.Width; + if ( aSize.Height <= 0 ) + aSize.Height = aDefaultSize.Height; + } + } + } + + if ( xToolkit.is() ) + { + if ( !xTopWindow.is() ) + { + // describe top window properties. + aDescriptor.Type = css::awt::WindowClass_TOP; + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >(); + aDescriptor.Bounds = css::awt::Rectangle( 0, 0, aSize.Width, aSize.Height ); + aDescriptor.WindowAttributes = 0; + + try + { + xTopWindow = css::uno::Reference< css::awt::XTopWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY ); + } + catch ( css::uno::RuntimeException& ) + { + throw; + } + catch ( css::uno::Exception& ) + { + } + } + + if ( xTopWindow.is() ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aLock.lock(); + m_bInitialized = sal_True; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + css::uno::Reference< css::awt::XWindow > xWindow( xTopWindow, css::uno::UNO_QUERY ); + xWindow->addWindowListener( css::uno::Reference< css::awt::XWindowListener >( + static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW )); + + xTopWindow->addTopWindowListener( css::uno::Reference< css::awt::XTopWindowListener >( + static_cast< ::cppu::OWeakObject* >( this ), css::uno::UNO_QUERY_THROW )); + + css::uno::Reference< css::awt::XWindow > xContainerWindow; + css::uno::Reference< css::awt::XWindow > xTabControl; + + // describe container window properties. + aDescriptor.Type = css::awt::WindowClass_SIMPLE; + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY ); + aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0); + aDescriptor.WindowAttributes = 0; + + xContainerWindow = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY ); + + // create a tab control window properties + aDescriptor.Type = css::awt::WindowClass_SIMPLE; + aDescriptor.WindowServiceName = DECLARE_ASCII("tabcontrol"); + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( xTopWindow, css::uno::UNO_QUERY ); + aDescriptor.Bounds = css::awt::Rectangle( 0,0,0,0 ); + aDescriptor.WindowAttributes = 0; + + xTabControl = css::uno::Reference< css::awt::XWindow >( xToolkit->createWindow( aDescriptor ), css::uno::UNO_QUERY ); + + if ( xContainerWindow.is() && xTabControl.is() ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aLock.lock(); + m_xTopWindow = xTopWindow; + m_xContainerWindow = xContainerWindow; + m_xTabControlWindow = xTabControl; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + xWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( pWindow ) + pWindow->Show( sal_True ); + + pWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + if ( pWindow ) + pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + + pWindow = VCLUnoHelper::GetWindow( xTabControl ); + if ( pWindow ) + { + pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + TabControl* pTabControl = (TabControl *)pWindow; + pTabControl->SetActivatePageHdl( LINK( this, TabWindow, Activate )); + pTabControl->SetDeactivatePageHdl( LINK( this, TabWindow, Deactivate )); + } + + implts_LayoutWindows(); + } + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XComponent +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL TabWindow::dispose() throw (css::uno::RuntimeException) +{ + // Send message to all listener and forget her references. + css::uno::Reference< css::lang::XComponent > xThis( + static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ); + css::lang::EventObject aEvent( xThis ); + + m_aListenerContainer.disposeAndClear( aEvent ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + css::uno::Reference< css::awt::XWindow > xTabControlWindow( m_xTabControlWindow ); + css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + css::uno::Reference< css::awt::XTopWindow > xTopWindow( m_xTopWindow ); + m_xTabControlWindow.clear(); + m_xContainerWindow.clear(); + m_xTopWindow.clear(); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + css::uno::Reference< css::lang::XComponent > xComponent( xTabControlWindow, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + + xComponent = css::uno::Reference< css::lang::XComponent >( xContainerWindow, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + + xComponent = css::uno::Reference< css::lang::XComponent >( xTopWindow, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aLock.lock(); + m_bDisposed = sal_True; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void SAL_CALL TabWindow::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + if ( m_bDisposed ) + return; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + m_aListenerContainer.addInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener ); +} + +void SAL_CALL TabWindow::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + if ( m_bDisposed ) + return; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + m_aListenerContainer.removeInterface( ::getCppuType( ( const css::uno::Reference< css::lang::XEventListener >* ) NULL ), xListener ); +} + +//--------------------------------------------------------------------------------------------------------- +// XEventListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL TabWindow::disposing( const css::lang::EventObject& ) +throw( css::uno::RuntimeException ) +{ +} + +//--------------------------------------------------------------------------------------------------------- +// XWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL TabWindow::windowResized( const css::awt::WindowEvent& ) +throw( css::uno::RuntimeException ) +{ + implts_LayoutWindows(); +} + +void SAL_CALL TabWindow::windowMoved( const css::awt::WindowEvent& ) +throw( css::uno::RuntimeException ) +{ +} + +void SAL_CALL TabWindow::windowShown( const css::lang::EventObject& ) +throw( css::uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + pTabControl->Show(); + + if ( m_xContainerWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + if ( pWindow ) + pWindow->Show(); + } +} + +void SAL_CALL TabWindow::windowHidden( const css::lang::EventObject& ) +throw( css::uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + if ( m_xContainerWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + if ( pWindow ) + pWindow->Hide(); + } + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + pTabControl->Hide(); +} + +//--------------------------------------------------------------------------------------------------------- +// XTopWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL TabWindow::windowOpened( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +void SAL_CALL TabWindow::windowClosing( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ + css::uno::Reference< css::lang::XComponent > xComponent( (OWeakObject *)this, css::uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); +} + +void SAL_CALL TabWindow::windowClosed( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +void SAL_CALL TabWindow::windowMinimized( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +void SAL_CALL TabWindow::windowNormalized( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +void SAL_CALL TabWindow::windowActivated( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +void SAL_CALL TabWindow::windowDeactivated( const css::lang::EventObject& ) +throw (css::uno::RuntimeException) +{ +} + +//--------------------------------------------------------------------------------------------------------- +// XSimpleTabController +//--------------------------------------------------------------------------------------------------------- + +::sal_Int32 SAL_CALL TabWindow::insertTab() +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + sal_Int32 nNextTabID( m_nNextTabID++ ); + + rtl::OUString aTitle; + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + pTabControl->InsertPage( sal_uInt16( nNextTabID ), aTitle ); + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_SendNotification( NOTIFY_INSERTED, nNextTabID ); + + return nNextTabID; +} + +void SAL_CALL TabWindow::removeTab( ::sal_Int32 ID ) +throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + { + sal_uInt16 nCurTabId = pTabControl->GetCurPageId(); + sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID )); + if ( nPos == TAB_PAGE_NOTFOUND ) + throw css::lang::IndexOutOfBoundsException(); + else + { + pTabControl->RemovePage( sal_uInt16( ID )); + nCurTabId = pTabControl->GetCurPageId(); + } + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_SendNotification( NOTIFY_REMOVED, ID ); + + // activate new tab if old tab was active! + nPos = pTabControl->GetPagePos( sal_uInt16( nCurTabId )); + if ( nPos != TAB_PAGE_NOTFOUND && nCurTabId != ID ) + activateTab( nCurTabId ); + } +} + +void SAL_CALL TabWindow::setTabProps( ::sal_Int32 ID, const css::uno::Sequence< css::beans::NamedValue >& Properties ) +throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + { + sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID )); + if ( nPos == TAB_PAGE_NOTFOUND ) + throw css::lang::IndexOutOfBoundsException(); + else + { + comphelper::SequenceAsHashMap aSeqHashMap( Properties ); + + ::rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID )); + sal_Int32 nNewPos = nPos; + + aTitle = aSeqHashMap.getUnpackedValueOrDefault< ::rtl::OUString >( + m_aTitlePropName, aTitle ); + pTabControl->SetPageText( sal_uInt16( ID ), aTitle ); + nNewPos = aSeqHashMap.getUnpackedValueOrDefault< sal_Int32 >( + m_aPosPropName, nNewPos ); + if ( nNewPos != sal_Int32( nPos )) + { + nPos = sal_uInt16( nNewPos ); + if ( nPos >= pTabControl->GetPageCount() ) + nPos = TAB_APPEND; + + pTabControl->RemovePage( sal_uInt16( ID )); + pTabControl->InsertPage( sal_uInt16( ID ), aTitle, nPos ); + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aLock.unlock(); + + css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq = getTabProps( ID ); + implts_SendNotification( NOTIFY_CHANGED, ID, aNamedValueSeq ); + } + } +} + +css::uno::Sequence< css::beans::NamedValue > SAL_CALL TabWindow::getTabProps( ::sal_Int32 ID ) +throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + css::uno::Sequence< css::beans::NamedValue > aNamedValueSeq; + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + { + sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID )); + if ( nPos == TAB_PAGE_NOTFOUND ) + throw css::lang::IndexOutOfBoundsException(); + else + { + rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID )); + nPos = pTabControl->GetPagePos( sal_uInt16( ID )); + + css::uno::Sequence< css::beans::NamedValue > aSeq( 2 ); + aSeq[0].Name = m_aTitlePropName; + aSeq[0].Value = css::uno::makeAny( aTitle ); + aSeq[1].Name = m_aPosPropName; + aSeq[1].Value = css::uno::makeAny( sal_Int32( nPos )); + return aSeq; + } + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + return aNamedValueSeq; +} + +void SAL_CALL TabWindow::activateTab( ::sal_Int32 ID ) +throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + { + sal_uInt16 nPos = pTabControl->GetPagePos( sal_uInt16( ID )); + if ( nPos == TAB_PAGE_NOTFOUND ) + throw css::lang::IndexOutOfBoundsException(); + else + { + sal_Int32 nOldID = pTabControl->GetCurPageId(); + rtl::OUString aTitle = pTabControl->GetPageText( sal_uInt16( ID )); + pTabControl->SetCurPageId( sal_uInt16( ID )); + pTabControl->SelectTabPage( sal_uInt16( ID )); + impl_SetTitle( aTitle ); + + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( nOldID != TAB_PAGE_NOTFOUND ) + implts_SendNotification( NOTIFY_DEACTIVATED, nOldID ); + implts_SendNotification( NOTIFY_ACTIVATED, ID ); + } + } +} + +::sal_Int32 SAL_CALL TabWindow::getActiveTabID() +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw css::lang::DisposedException(); + + TabControl* pTabControl = impl_GetTabControl( m_xTabControlWindow ); + if ( pTabControl ) + { + sal_uInt16 nID = pTabControl->GetCurPageId(); + if ( nID == TAB_PAGE_NOTFOUND ) + return -1; + else + return sal_Int32( nID ); + } + + return -1; + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void SAL_CALL TabWindow::addTabListener( + const css::uno::Reference< css::awt::XTabListener >& xListener ) +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + if ( m_bDisposed ) + return; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + m_aListenerContainer.addInterface( + ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener ); +} + +void SAL_CALL TabWindow::removeTabListener( const css::uno::Reference< css::awt::XTabListener >& xListener ) +throw (css::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ResetableGuard aLock( m_aLock ); + if ( m_bDisposed ) + return; + aLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + m_aListenerContainer.removeInterface( + ::getCppuType( ( const css::uno::Reference< css::awt::XTabListener >* ) NULL ), xListener ); +} + +//--------------------------------------------------------------------------------------------------------- +// OPropertySetHelper +//--------------------------------------------------------------------------------------------------------- + +// XPropertySet helper +sal_Bool SAL_CALL TabWindow::convertFastPropertyValue( css::uno::Any& aConvertedValue , + css::uno::Any& aOldValue , + sal_Int32 nHandle , + const css::uno::Any& aValue ) +throw( css::lang::IllegalArgumentException ) +{ + // Initialize state with sal_False !!! + // (Handle can be invalid) + sal_Bool bReturn = sal_False; + + switch( nHandle ) + { + case TABWINDOW_PROPHANDLE_PARENTWINDOW : + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny( m_xContainerWindow ), + aValue, + aOldValue, + aConvertedValue); + break; + + case TABWINDOW_PROPHANDLE_TOPWINDOW : + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny( m_xTopWindow ), + aValue, + aOldValue, + aConvertedValue); + break; + } + + // Return state of operation. + return bReturn ; +} + +void SAL_CALL TabWindow::setFastPropertyValue_NoBroadcast( sal_Int32, + const css::uno::Any&) +throw( css::uno::Exception ) +{ +} + +void SAL_CALL TabWindow::getFastPropertyValue( css::uno::Any& aValue , + sal_Int32 nHandle ) const +{ + switch( nHandle ) + { + case TABWINDOW_PROPHANDLE_PARENTWINDOW: + aValue <<= m_xContainerWindow; + break; + case TABWINDOW_PROPHANDLE_TOPWINDOW: + aValue <<= m_xTopWindow; + break; + } +} + +::cppu::IPropertyArrayHelper& SAL_CALL TabWindow::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. + // "sal_True" say: Table is sorted by name. + static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL TabWindow::getPropertySetInfo() +throw ( css::uno::RuntimeException ) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static css::uno::Reference< css::beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static css::uno::Reference< css::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +const css::uno::Sequence< css::beans::Property > TabWindow::impl_getStaticPropertyDescriptor() +{ + // Create a new static property array to initialize sequence! + // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! + // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! + // It's necessary for methods of OPropertySetHelper. + // ATTENTION: + // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! + + static const com::sun::star::beans::Property pProperties[] = + { + com::sun::star::beans::Property( TABWINDOW_PROPNAME_PARENTWINDOW, + TABWINDOW_PROPHANDLE_PARENTWINDOW, + ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL), + com::sun::star::beans::PropertyAttribute::READONLY ), + com::sun::star::beans::Property( TABWINDOW_PROPNAME_TOPWINDOW, + TABWINDOW_PROPHANDLE_TOPWINDOW, + ::getCppuType((const css::uno::Reference< css::awt::XWindow >*)NULL), + com::sun::star::beans::PropertyAttribute::READONLY ) + }; // Use it to initialize sequence! + static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, TABWINDOW_PROPCOUNT ); + + // Return static "PropertyDescriptor" + return lPropertyDescriptor; +} + +} |