blob: e3a05683a7ff611fa2164c18f5dc6f2df9a143be [file] [log] [blame]
/**************************************************************
*
* 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_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;
}
}