diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2010-06-15 05:33:03 +0200 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2010-06-15 05:33:03 +0200 |
commit | d3996884eefaa66b329e4aecba095bea696cf696 (patch) | |
tree | ff5127f7d6f05f537115085f2c57ac01881da092 /svtools/source/control | |
parent | 355b32c362ddba7e7af31961fbda61ba5f83b9d3 (diff) | |
parent | ff33409c01b082dc5a0e501b0f4c2f97131fcd52 (diff) |
calctabcolor: rebased to DEV300_m82.
Diffstat (limited to 'svtools/source/control')
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/calendar.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/calendar.src | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/collatorres.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/ctrlbox.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/ctrlbox.src | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/ctrltool.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/ctrltool.src | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/indexentryres.cxx | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/makefile.mk | 4 | ||||
-rw-r--r-- | svtools/source/control/toolbarmenu.cxx | 1805 | ||||
-rw-r--r-- | svtools/source/control/toolbarmenuacc.cxx | 1003 | ||||
-rw-r--r-- | svtools/source/control/toolbarmenuimp.hxx | 314 | ||||
-rw-r--r-- | svtools/source/control/valueacc.cxx | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | svtools/source/control/valueimp.hxx | 1 | ||||
-rw-r--r-- | svtools/source/control/valueset.cxx | 51 |
15 files changed, 3165 insertions, 36 deletions
diff --git a/svtools/source/control/calendar.cxx b/svtools/source/control/calendar.cxx index c83ffa3ed70f..f7b49ac57eeb 100644..100755 --- a/svtools/source/control/calendar.cxx +++ b/svtools/source/control/calendar.cxx @@ -59,7 +59,7 @@ #include <com/sun/star/i18n/CalendarFieldIndex.hpp> #define _SV_CALENDAR_CXX -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include <svtools/svtdata.hxx> #include <calendar.hxx> diff --git a/svtools/source/control/calendar.src b/svtools/source/control/calendar.src index 15c82cfdd184..4dd31765a5c1 100644..100755 --- a/svtools/source/control/calendar.src +++ b/svtools/source/control/calendar.src @@ -25,7 +25,7 @@ * ************************************************************************/ -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> String STR_SVT_CALENDAR_DAY { Text [ en-US ] = "Day" ; diff --git a/svtools/source/control/collatorres.cxx b/svtools/source/control/collatorres.cxx index 23a84e757ebe..9988bfdadbb9 100644..100755 --- a/svtools/source/control/collatorres.cxx +++ b/svtools/source/control/collatorres.cxx @@ -29,7 +29,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svtools.hxx" #include <svtools/svtdata.hxx> -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include <collatorres.hxx> diff --git a/svtools/source/control/ctrlbox.cxx b/svtools/source/control/ctrlbox.cxx index 2f692944d3c7..d44b18a29ae1 100644..100755 --- a/svtools/source/control/ctrlbox.cxx +++ b/svtools/source/control/ctrlbox.cxx @@ -40,7 +40,7 @@ #include <unotools/charclass.hxx> #include <svtools/svtdata.hxx> -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include <ctrlbox.hxx> #include <ctrltool.hxx> diff --git a/svtools/source/control/ctrlbox.src b/svtools/source/control/ctrlbox.src index 0c63aef259b3..95440c905d89 100644..100755 --- a/svtools/source/control/ctrlbox.src +++ b/svtools/source/control/ctrlbox.src @@ -24,7 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #ifndef IMAGE_STDBTN_COLOR #define IMAGE_STDBTN_COLOR Color { Red = 0xFFFF; Green = 0x0000; Blue = 0xFFFF; } diff --git a/svtools/source/control/ctrltool.cxx b/svtools/source/control/ctrltool.cxx index 9abd14331fe4..bd965aca66a6 100644..100755 --- a/svtools/source/control/ctrltool.cxx +++ b/svtools/source/control/ctrltool.cxx @@ -42,7 +42,7 @@ #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include <svtools/svtdata.hxx> #include <ctrltool.hxx> diff --git a/svtools/source/control/ctrltool.src b/svtools/source/control/ctrltool.src index 3e1c1ba884f8..72420af4908e 100644..100755 --- a/svtools/source/control/ctrltool.src +++ b/svtools/source/control/ctrltool.src @@ -24,7 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> String STR_SVT_STYLE_LIGHT { diff --git a/svtools/source/control/indexentryres.cxx b/svtools/source/control/indexentryres.cxx index 32e3aa14c0dc..5a79edab5b77 100644..100755 --- a/svtools/source/control/indexentryres.cxx +++ b/svtools/source/control/indexentryres.cxx @@ -29,7 +29,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svtools.hxx" #include <svtools/svtdata.hxx> -#include <svl/svtools.hrc> +#include <svtools/svtools.hrc> #include <indexentryres.hxx> diff --git a/svtools/source/control/makefile.mk b/svtools/source/control/makefile.mk index a40a81163eb3..a2e622730635 100644..100755 --- a/svtools/source/control/makefile.mk +++ b/svtools/source/control/makefile.mk @@ -51,7 +51,9 @@ EXCEPTIONSFILES=\ $(SLO)$/scriptedtext.obj\ $(SLO)$/fmtfield.obj \ $(SLO)$/inettbc.obj \ - $(SLO)$/valueacc.obj + $(SLO)$/valueacc.obj \ + $(SLO)$/toolbarmenu.obj \ + $(SLO)$/toolbarmenuacc.obj SLOFILES=\ $(EXCEPTIONSFILES) \ diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx new file mode 100644 index 000000000000..f07ebd7fe8cd --- /dev/null +++ b/svtools/source/control/toolbarmenu.cxx @@ -0,0 +1,1805 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> +#include <comphelper/processfactory.hxx> + +#include <vcl/dockwin.hxx> +#include <vcl/decoview.hxx> +#include <vcl/image.hxx> +#include <vcl/taskpanelist.hxx> +#include <vcl/toolbox.hxx> + +#include "svtools/valueset.hxx" +#include "svtools/toolbarmenu.hxx" +#include "toolbarmenuimp.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::accessibility; + +namespace svtools { + +// -------------------------------------------------------------------- + +static Window* GetTopMostParentSystemWindow( Window* pWindow ) +{ + OSL_ASSERT( pWindow ); + if ( pWindow ) + { + // ->manually search topmost system window + // required because their might be another system window between this and the top window + pWindow = pWindow->GetParent(); + SystemWindow* pTopMostSysWin = NULL; + while ( pWindow ) + { + if ( pWindow->IsSystemWindow() ) + pTopMostSysWin = (SystemWindow*)pWindow; + pWindow = pWindow->GetParent(); + } + pWindow = pTopMostSysWin; + OSL_ASSERT( pWindow ); + return pWindow; + } + + return NULL; +} + +// -------------------------------------------------------------------- + +void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits ) +{ + mnEntryId = nEntryId; + mnBits = nBits; + + mbHasText = false; + mbHasImage = false; + mbChecked = false; + mbEnabled = true; + + mpControl = NULL; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits ) +: mrMenu( rMenu ) +{ + init( nEntryId, nBits ); + + maText = rText; + mbHasText = true; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits ) +: mrMenu( rMenu ) +{ + init( nEntryId, nBits ); + + maImage = rImage; + mbHasImage = true; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits ) +: mrMenu( rMenu ) +{ + init( nEntryId, nBits ); + + maText = rText; + mbHasText = true; + + maImage = rImage; + mbHasImage = true; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits ) +: mrMenu( rMenu ) +{ + init( nEntryId, nBits ); + + if( pControl ) + { + mpControl = pControl; + mpControl->Show(); + } +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry::~ToolbarMenuEntry() +{ + if( mxAccContext.is() ) + { + Reference< XComponent > xComponent( mxAccContext, UNO_QUERY ); + if( xComponent.is() ) + xComponent->dispose(); + mxAccContext.clear(); + } + delete mpControl; +} + +// -------------------------------------------------------------------- + +const Reference< XAccessibleContext >& ToolbarMenuEntry::GetAccessible( bool bCreate /* = false */ ) +{ + if( !mxAccContext.is() && bCreate ) + { + if( mpControl ) + { + mxAccContext = Reference< XAccessibleContext >( mpControl->GetAccessible( TRUE ), UNO_QUERY ); + } + else + { + mxAccContext = Reference< XAccessibleContext >( new ToolbarMenuEntryAcc( this ) ); + } + } + + return mxAccContext; +} + +// -------------------------------------------------------------------- + +sal_Int32 ToolbarMenuEntry::getAccessibleChildCount() throw (RuntimeException) +{ + if( mpControl ) + { + const Reference< XAccessibleContext >& xContext = GetAccessible( true ); + if( xContext.is() ) + { + return xContext->getAccessibleChildCount(); + } + } + return 1; +} + +// -------------------------------------------------------------------- + +Reference< XAccessible > ToolbarMenuEntry::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const Reference< XAccessibleContext >& xContext = GetAccessible( true ); + if( mpControl ) + { + if( xContext.is() ) + { + return xContext->getAccessibleChild(index); + } + } + else if( index == 0 ) + { + Reference< XAccessible > xRet( xContext, UNO_QUERY ); + if( xRet.is() ) + return xRet; + } + + throw IndexOutOfBoundsException(); +} + +// -------------------------------------------------------------------- + +ToolbarMenu_Impl::ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame ) +: mrMenu( rMenu ) +, mxFrame( xFrame ) +, mxServiceManager( ::comphelper::getProcessServiceFactory() ) +, mnCheckPos(0) +, mnImagePos(0) +, mnTextPos(0) +, mnHighlightedEntry(-1) +, mnSelectedEntry(-1) +, mnLastColumn(0) +{ +} + +// -------------------------------------------------------------------- + +ToolbarMenu_Impl::~ToolbarMenu_Impl() +{ + setAccessible( 0 ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu_Impl::setAccessible( ToolbarMenuAcc* pAccessible ) +{ + if( mxAccessible.get() != pAccessible ) + { + if( mxAccessible.is() ) + mxAccessible->dispose(); + + mxAccessible.set( pAccessible ); + } +} + +// ----------------------------------------------------------------------- + +void ToolbarMenu_Impl::fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ) +{ + if( mxAccessible.is() ) + mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue ); +} + +// ----------------------------------------------------------------------- + +bool ToolbarMenu_Impl::hasAccessibleListeners() +{ + return( mxAccessible.is() && mxAccessible->HasAccessibleListeners() ); +} + +// -------------------------------------------------------------------- + +sal_Int32 ToolbarMenu_Impl::getAccessibleChildCount() throw (RuntimeException) +{ + sal_Int32 nCount = 0; + const int nEntryCount = maEntryVector.size(); + for( int nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = maEntryVector[nEntry]; + if( pEntry ) + { + if( pEntry->mpControl ) + { + nCount += pEntry->getAccessibleChildCount(); + } + else + { + nCount += 1; + } + } + } + + return nCount; +} + +// -------------------------------------------------------------------- + +Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const int nEntryCount = maEntryVector.size(); + for( int nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = maEntryVector[nEntry]; + if( pEntry ) + { + const sal_Int32 nCount = pEntry->getAccessibleChildCount(); + if( index < nCount ) + { + return pEntry->getAccessibleChild( index ); + } + index -= nCount; + } + } + + throw IndexOutOfBoundsException(); +} + +// -------------------------------------------------------------------- + +Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const int nEntryCount = maEntryVector.size(); + for( int nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = maEntryVector[nEntry]; + if( pEntry && (pEntry->mpControl == pControl) ) + { + return pEntry->getAccessibleChild( childIndex ); + } + } + + throw IndexOutOfBoundsException(); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu_Impl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const int nEntryCount = maEntryVector.size(); + for( int nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = maEntryVector[nEntry]; + if( pEntry ) + { + const sal_Int32 nCount = pEntry->getAccessibleChildCount(); + if( nChildIndex < nCount ) + { + if( pEntry->mpControl ) + { + Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW ); + xSel->selectAccessibleChild(nChildIndex); + } + else if( pEntry->mnEntryId != TITLE_ID ) + { + mrMenu.implSelectEntry( nEntry ); + } + return; + } + nChildIndex -= nCount; + } + } + + throw IndexOutOfBoundsException(); +} + +// -------------------------------------------------------------------- + +sal_Bool ToolbarMenu_Impl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const int nEntryCount = maEntryVector.size(); + for( int nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = maEntryVector[nEntry]; + if( pEntry ) + { + const sal_Int32 nCount = pEntry->getAccessibleChildCount(); + if( nChildIndex < nCount ) + { + if( mnHighlightedEntry == nEntry ) + { + if( pEntry->mpControl ) + { + Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW ); + xSel->isAccessibleChildSelected(nChildIndex); + } + return true; + } + else + { + return false; + } + } + nChildIndex -= nCount; + } + } + + throw IndexOutOfBoundsException(); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu_Impl::clearAccessibleSelection() +{ + if( mnHighlightedEntry != -1 ) + { + mrMenu.implHighlightEntry( mnHighlightedEntry, false ); + mnHighlightedEntry = -1; + } +} + + +// -------------------------------------------------------------------- + +void ToolbarMenu_Impl::notifyHighlightedEntry() +{ + if( hasAccessibleListeners() ) + { + ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry ); + if( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) ) + { + Any aNew; + Any aOld( mxOldSelection ); + if( pEntry->mpControl ) + { + sal_Int32 nChildIndex = 0; + // todo: if other controls than ValueSet are allowed, addapt this code + ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl ); + if( pValueSet ) + nChildIndex = static_cast< sal_Int32 >( pValueSet->GetItemPos( pValueSet->GetSelectItemId() ) ); + + if( nChildIndex >= pEntry->getAccessibleChildCount() ) + return; + + aNew <<= getAccessibleChild( pEntry->mpControl, nChildIndex ); + } + else + { + aNew <<= pEntry->GetAccessible(true); + } + + fireAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOld, aNew ); + fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOld, aNew ); + fireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) ); + aNew >>= mxOldSelection; + } + } +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry* ToolbarMenu_Impl::implGetEntry( int nEntry ) const +{ + if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) ) + return NULL; + + return maEntryVector[nEntry]; +} + + +// -------------------------------------------------------------------- + +IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl ) +{ + (void)pControl; + mpImpl->notifyHighlightedEntry(); + return 0; +} + +// ==================================================================== + +ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, WinBits nBits ) +: DockingWindow(pParentWindow, nBits) +{ + implInit(rFrame); +} + +// -------------------------------------------------------------------- + +ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, const ResId& rResId ) +: DockingWindow(pParentWindow, rResId) +{ + implInit(rFrame); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::implInit(const Reference< XFrame >& rFrame) +{ + mpImpl = new ToolbarMenu_Impl( *this, rFrame ); + + initWindow(); + + Window* pWindow = GetTopMostParentSystemWindow( this ); + if ( pWindow ) + ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( this ); +} + +// -------------------------------------------------------------------- + +ToolbarMenu::~ToolbarMenu() +{ + Window* pWindow = GetTopMostParentSystemWindow( this ); + if ( pWindow ) + ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( this ); + + if ( mpImpl->mxStatusListener.is() ) + { + mpImpl->mxStatusListener->dispose(); + mpImpl->mxStatusListener.clear(); + } + + // delete all menu entries + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + delete mpImpl->maEntryVector[nEntry]; + } + + delete mpImpl; +} + +// -------------------------------------------------------------------- + +int ToolbarMenu::getSelectedEntryId() const +{ + ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnSelectedEntry ); + return pEntry ? pEntry->mnEntryId : -1; +} + +// -------------------------------------------------------------------- + +int ToolbarMenu::getHighlightedEntryId() const +{ + ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry ); + return pEntry ? pEntry->mnEntryId : -1; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::checkEntry( int nEntryId, bool bChecked ) +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry && pEntry->mbChecked != bChecked ) + { + pEntry->mbChecked = bChecked; + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +bool ToolbarMenu::isEntryChecked( int nEntryId ) const +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + return pEntry && pEntry->mbChecked; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::enableEntry( int nEntryId, bool bEnable ) +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry && pEntry->mbEnabled != bEnable ) + { + pEntry->mbEnabled = bEnable; + if( pEntry->mpControl ) + { + pEntry->mpControl->Enable( bEnable ); + + // hack for the valueset to make it paint itself anew + pEntry->mpControl->Resize(); + } + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +bool ToolbarMenu::isEntryEnabled( int nEntryId ) const +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + return pEntry && pEntry->mbEnabled; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::setEntryText( int nEntryId, const String& rStr ) +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry && pEntry->maText != rStr ) + { + pEntry->maText = rStr; + mpImpl->maSize = implCalcSize(); + if( IsVisible() ) + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +const String& ToolbarMenu::getEntryText( int nEntryId ) const +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry ) + return pEntry->maText; + else + { + static String aEmptyStr; + return aEmptyStr; + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage ) +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry && pEntry->maImage != rImage ) + { + pEntry->maImage = rImage; + mpImpl->maSize = implCalcSize(); + if( IsVisible() ) + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +const Image& ToolbarMenu::getEntryImage( int nEntryId ) const +{ + ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId ); + if( pEntry ) + return pEntry->maImage; + else + { + static Image aEmptyImage; + return aEmptyImage; + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::initWindow() +{ + const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); + + SetControlBackground( GetSettings().GetStyleSettings().GetFaceGradientColor() ); + + SetPointFont( rStyleSettings.GetMenuFont() ); + SetBackground( Wallpaper( GetControlBackground() ) ); + SetTextColor( rStyleSettings.GetMenuTextColor() ); + SetTextFillColor(); + SetLineColor(); + + mpImpl->maSize = implCalcSize(); +} + +// -------------------------------------------------------------------- + +Size ToolbarMenu::implCalcSize() +{ + const long nFontHeight = GetTextHeight(); + long nExtra = nFontHeight/4; + + Size aSz; + Size aMaxImgSz; + long nMaxTextWidth = 0; + long nMinMenuItemHeight = nFontHeight+2; + sal_Bool bCheckable = sal_False; + + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + + const StyleSettings& rSettings = GetSettings().GetStyleSettings(); + const bool bUseImages = rSettings.GetUseImagesInMenus(); + + // get maximum image size + if( bUseImages ) + { + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + if( pEntry && pEntry->mbHasImage ) + { + Size aImgSz( pEntry->maImage.GetSizePixel() ); + nMinMenuItemHeight = std::max( nMinMenuItemHeight, aImgSz.Height() + 6 ); + aMaxImgSz.Width() = std::max( aMaxImgSz.Width(), aImgSz.Width() ); + } + } + } + + mpImpl->mnCheckPos = nExtra; + mpImpl->mnImagePos = nExtra; + mpImpl->mnTextPos = mpImpl->mnImagePos + aMaxImgSz.Width(); + + if ( aMaxImgSz.Width() ) + mpImpl->mnTextPos += std::max( nExtra, 7L ); + if ( bCheckable ) + mpImpl->mnTextPos += 16; + + // set heights, calc maximum width + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + + if( pEntry ) + { + if ( ( pEntry->mnBits ) & ( MIB_RADIOCHECK | MIB_CHECKABLE ) ) + bCheckable = sal_True; + + // Text: + if( pEntry->mbHasText || pEntry->mbHasImage ) + { + pEntry->maSize.Height() = nMinMenuItemHeight; + + if( pEntry->mbHasText ) + { + long nTextWidth = GetCtrlTextWidth( pEntry->maText ) + mpImpl->mnTextPos + nExtra; + nMaxTextWidth = std::max( nTextWidth, nMaxTextWidth ); + } + } + // Control: + else if( pEntry->mpControl ) + { + Size aControlSize( pEntry->mpControl->GetOutputSizePixel() ); + + nMaxTextWidth = std::max( aControlSize.Width(), nMaxTextWidth ); + pEntry->maSize.Height() = aControlSize.Height() + 1; + } + + } + } + + aSz.Width() = nMaxTextWidth + (BORDER_X<<1); + + // positionate controls + int nY = BORDER_Y; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + + if( pEntry ) + { + pEntry->maSize.Width() = nMaxTextWidth; + + if( pEntry->mpControl ) + { + Size aControlSize( pEntry->mpControl->GetOutputSizePixel() ); + Point aControlPos( (aSz.Width() - aControlSize.Width())>>1, nY); + + pEntry->mpControl->SetPosPixel( aControlPos ); + + pEntry->maRect = Rectangle( aControlPos, aControlSize ); + } + else + { + pEntry->maRect = Rectangle( Point( 0, nY ), pEntry->maSize ); + } + + nY += pEntry->maSize.Height(); + } + else + { + nY += SEPARATOR_HEIGHT; + } + } + + aSz.Height() += nY + BORDER_Y; + + return aSz; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::highlightFirstEntry() +{ + implChangeHighlightEntry( 0 ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::GetFocus() +{ + if( mpImpl->mnHighlightedEntry == -1 ) + implChangeHighlightEntry( 0 ); + + DockingWindow::GetFocus(); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::LoseFocus() +{ + if( mpImpl->mnHighlightedEntry != -1 ) + implChangeHighlightEntry( -1 ); + + DockingWindow::LoseFocus(); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits ) +{ + appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits ) +{ + appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, nItemBits ) ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits ) +{ + appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, rStr, nItemBits ) ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits ) +{ + appendEntry( new ToolbarMenuEntry( *this, nEntryId, pControl, nItemBits ) ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry ) +{ + mpImpl->maEntryVector.push_back( pEntry ); + mpImpl->maSize = implCalcSize(); + if( IsVisible() ) + Invalidate(); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::appendSeparator() +{ + appendEntry( 0 ); +} + +// -------------------------------------------------------------------- + +/** creates an empty ValueSet that is initialized and can be inserted with appendEntry. */ +ValueSet* ToolbarMenu::createEmptyValueSetControl() +{ + ValueSet* pSet = new ValueSet( this, WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT ); + pSet->EnableFullItemMode( FALSE ); + pSet->SetColor( GetControlBackground() ); + pSet->SetHighlightHdl( LINK( this, ToolbarMenu, HighlightHdl ) ); + return pSet; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const +{ + return mpImpl->implGetEntry( nEntry ); +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const +{ + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* p = mpImpl->maEntryVector[nEntry]; + if( p && p->mnEntryId == nEntryId ) + { + return p; + } + } + + return NULL; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::implHighlightEntry( int nHighlightEntry, bool bHighlight ) +{ + Size aSz( GetOutputSizePixel() ); + long nX = 0, nY = 0; + + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + if( pEntry && (nEntry == nHighlightEntry) ) + { + // no highlights for controls only items + if( pEntry->mpControl ) + { + if( !bHighlight ) + { + ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl ); + if( pValueSet ) + { + pValueSet->SetNoSelection(); + } + } + break; + } + + bool bRestoreLineColor = false; + Color oldLineColor; + bool bDrawItemRect = true; + + Rectangle aItemRect( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) ); + if ( pEntry->mnBits & MIB_POPUPSELECT ) + { + long nFontHeight = GetTextHeight(); + aItemRect.Right() -= nFontHeight + nFontHeight/4; + } + + if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) ) + { + Size aPxSize( GetOutputSizePixel() ); + Push( PUSH_CLIPREGION ); + IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) ) ); + Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) ); + DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, + Region( aCtrlRect ), + CTRL_STATE_ENABLED, + ImplControlValue(), + OUString() ); + if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) ) + { + bDrawItemRect = false; + if( FALSE == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM, + Region( aItemRect ), + CTRL_STATE_SELECTED | ( pEntry->mbEnabled? CTRL_STATE_ENABLED: 0 ), + ImplControlValue(), + OUString() ) ) + { + bDrawItemRect = bHighlight; + } + } + else + bDrawItemRect = bHighlight; + Pop(); + } + if( bDrawItemRect ) + { + if ( bHighlight ) + { + if( pEntry->mbEnabled ) + SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() ); + else + { + SetFillColor(); + oldLineColor = GetLineColor(); + SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() ); + bRestoreLineColor = true; + } + } + else + SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() ); + + DrawRect( aItemRect ); + } + implPaint( pEntry, bHighlight ); + if( bRestoreLineColor ) + SetLineColor( oldLineColor ); + break; + } + + nY += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT; + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::implSelectEntry( int nSelectedEntry ) +{ + mpImpl->mnSelectedEntry = nSelectedEntry; + + ToolbarMenuEntry* pEntry = NULL; + if( nSelectedEntry != -1 ) + pEntry = mpImpl->maEntryVector[ nSelectedEntry ]; + + if( pEntry ) + mpImpl->maSelectHdl.Call( this ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt ) +{ + implHighlightEntry( rMEvt, true ); + + implSelectEntry( mpImpl->mnHighlightedEntry ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::MouseButtonUp( const MouseEvent& ) +{ +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::MouseMove( const MouseEvent& rMEvt ) +{ + if ( !IsVisible() ) + return; + + implHighlightEntry( rMEvt, false ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown ) +{ + long nY = 0; + long nMouseY = rMEvt.GetPosPixel().Y(); + Size aOutSz = GetOutputSizePixel(); + if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) ) + { + bool bHighlighted = FALSE; + + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + if( pEntry ) + { + long nOldY = nY; + nY += pEntry->maSize.Height(); + + if( pEntry->mnEntryId != TITLE_ID ) + { + if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) ) + { + if( bMBDown ) + { + if( nEntry != mpImpl->mnHighlightedEntry ) + { + implChangeHighlightEntry( nEntry ); + } + } + else + { + if ( nEntry != mpImpl->mnHighlightedEntry ) + { + implChangeHighlightEntry( nEntry ); + } + } + bHighlighted = true; + } + } + } + else + { + nY += SEPARATOR_HEIGHT; + } + } + if ( !bHighlighted ) + implChangeHighlightEntry( -1 ); + } + else + { + implChangeHighlightEntry( -1 ); + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::implChangeHighlightEntry( int nEntry ) +{ + if( mpImpl->mnHighlightedEntry != -1 ) + { + implHighlightEntry( mpImpl->mnHighlightedEntry, false ); + } + + mpImpl->mnHighlightedEntry = nEntry; + Invalidate(); + + if( mpImpl->mnHighlightedEntry != -1 ) + { + implHighlightEntry( mpImpl->mnHighlightedEntry, true ); + } + + mpImpl->notifyHighlightedEntry(); +} + +// -------------------------------------------------------------------- + +static bool implCheckSubControlCursorMove( Control* pControl, bool bUp, int& nLastColumn ) +{ + ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl ); + if( pValueSet ) + { + USHORT nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() ); + if( nItemPos != VALUESET_ITEM_NOTFOUND ) + { + const USHORT nColCount = pValueSet->GetColCount(); + const USHORT nLine = nItemPos / nColCount; + + nLastColumn = nItemPos - (nLine * nColCount); + + if( bUp ) + { + return nLine > 0; + } + else + { + const USHORT nLineCount = (pValueSet->GetItemCount() + nColCount - 1) / nColCount; + return (nLine+1) < nLineCount; + } + } + } + + return false; +} + +// -------------------------------------------------------------------- + +ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd ) +{ + int n = 0, nLoop = 0; + if( !bHomeEnd ) + { + n = mpImpl->mnHighlightedEntry; + if( n == -1 ) + { + if( bUp ) + n = 0; + else + n = mpImpl->maEntryVector.size()-1; + } + else + { + // if we have a currently selected entry and + // cursor keys are used than check if this entry + // has a control that can use those cursor keys + ToolbarMenuEntry* pData = mpImpl->maEntryVector[n]; + if( pData && pData->mpControl && !pData->mbHasText ) + { + if( implCheckSubControlCursorMove( pData->mpControl, bUp, mpImpl->mnLastColumn ) ) + return pData; + } + } + nLoop = n; + } + else + { + // absolute positioning + if( bUp ) + { + n = mpImpl->maEntryVector.size(); + nLoop = n-1; + } + else + { + n = -1; + nLoop = mpImpl->maEntryVector.size()-1; + } + } + + do + { + if( bUp ) + { + if ( n ) + n--; + else + if( mpImpl->mnHighlightedEntry == -1 ) + n = mpImpl->maEntryVector.size()-1; + else + break; + } + else + { + if( n < ((int)mpImpl->maEntryVector.size()-1) ) + n++; + else + if( mpImpl->mnHighlightedEntry == -1 ) + n = 0; + else + break; + } + + ToolbarMenuEntry* pData = mpImpl->maEntryVector[n]; + if( pData && (pData->mnEntryId != TITLE_ID) ) + { + implChangeHighlightEntry( n ); + return pData; + } + } while ( n != nLoop ); + + return 0; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu_Impl::implHighlightControl( USHORT nCode, Control* pControl ) +{ + ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl ); + if( pValueSet ) + { + const USHORT nItemCount = pValueSet->GetItemCount(); + USHORT nItemPos = VALUESET_ITEM_NOTFOUND; + switch( nCode ) + { + case KEY_UP: + { + const USHORT nColCount = pValueSet->GetColCount(); + const USHORT nLastLine = nItemCount / nColCount; + nItemPos = std::min( ((nLastLine-1) * nColCount) + mnLastColumn, nItemCount-1 ); + break; + } + case KEY_DOWN: + nItemPos = std::min( mnLastColumn, nItemCount-1 ); + break; + case KEY_END: + nItemPos = nItemCount -1; + break; + case KEY_HOME: + nItemPos = 0; + break; + } + pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) ); + notifyHighlightedEntry(); + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::KeyInput( const KeyEvent& rKEvent ) +{ + Control* pForwardControl = 0; + USHORT nCode = rKEvent.GetKeyCode().GetCode(); + switch ( nCode ) + { + case KEY_UP: + case KEY_DOWN: + { + int nOldEntry = mpImpl->mnHighlightedEntry; + ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false ); + if( p && p->mpControl ) + { + if( nOldEntry != mpImpl->mnHighlightedEntry ) + { + mpImpl->implHighlightControl( nCode, p->mpControl ); + } + else + { + // in case we are in a system floating window, GrabFocus does not work :-/ + pForwardControl = p->mpControl; + } + } + } + break; + case KEY_END: + case KEY_HOME: + { + ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true ); + if( p && p->mpControl ) + { + mpImpl->implHighlightControl( nCode, p->mpControl ); + } + } + break; + case KEY_F6: + case KEY_ESCAPE: + { + // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document + if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() ) + break; + + implSelectEntry( -1 ); + } + break; + + case KEY_RETURN: + { + ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry ); + if ( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) ) + { + if( pEntry->mpControl ) + { + pForwardControl = pEntry->mpControl; + } + else + { + implSelectEntry( mpImpl->mnHighlightedEntry ); + } + } + } + break; + default: + { + ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry ); + if ( pEntry && pEntry->mbEnabled && pEntry->mpControl && !pEntry->mbHasText ) + { + pForwardControl = pEntry->mpControl; + } + } + + } + if( pForwardControl ) + pForwardControl->KeyInput( rKEvent ); + +} + +// -------------------------------------------------------------------- +static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRect, bool i_bHighlight ) +{ + BOOL bNativeOk = FALSE; + if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) ) + { + ImplControlValue aControlValue; + Region aCtrlRegion( i_rRect ); + ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED; + + aControlValue.setTristateVal( BUTTONVALUE_ON ); + + bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON, + aCtrlRegion, nState, aControlValue, + rtl::OUString() ); + } + + if( ! bNativeOk ) + { + const StyleSettings& rSettings = i_pWindow->GetSettings().GetStyleSettings(); + Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() ); + i_pWindow->DrawSelectionBackground( i_rRect, 0, i_bHighlight, TRUE, FALSE, 2, NULL, &aColor ); + } +} + +static long ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth ) +{ + rMaxWidth = rCheckHeight = rRadioHeight = 0; + + ImplControlValue aVal; + Region aNativeBounds; + Region aNativeContent; + Point tmp( 0, 0 ); + Region aCtrlRegion( Rectangle( tmp, Size( 100, 15 ) ) ); + if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) ) + { + if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP), + ControlPart(PART_MENU_ITEM_CHECK_MARK), + aCtrlRegion, + ControlState(CTRL_STATE_ENABLED), + aVal, + OUString(), + aNativeBounds, + aNativeContent ) + ) + { + rCheckHeight = aNativeBounds.GetBoundRect().GetHeight(); + rMaxWidth = aNativeContent.GetBoundRect().GetWidth(); + } + } + if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) ) + { + if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP), + ControlPart(PART_MENU_ITEM_RADIO_MARK), + aCtrlRegion, + ControlState(CTRL_STATE_ENABLED), + aVal, + OUString(), + aNativeBounds, + aNativeContent ) + ) + { + rRadioHeight = aNativeBounds.GetBoundRect().GetHeight(); + rMaxWidth = Max (rMaxWidth, aNativeContent.GetBoundRect().GetWidth()); + } + } + return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight; +} + +void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted ) +{ + USHORT nBorder = 0; long nStartY = 0; // from Menu implementations, needed when we support native menu background & scrollable menu + + long nFontHeight = GetTextHeight(); +// long nExtra = nFontHeight/4; + + long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0; + ImplGetNativeCheckAndRadioSize( this, nCheckHeight, nRadioHeight, nMaxCheckWidth ); + + DecorationView aDecoView( this ); + const StyleSettings& rSettings = GetSettings().GetStyleSettings(); + const bool bUseImages = rSettings.GetUseImagesInMenus(); + + int nOuterSpace = 0; // ImplGetSVData()->maNWFData.mnMenuFormatExtraBorder; + Point aTopLeft( nOuterSpace, nOuterSpace ), aTmpPos; + + Size aOutSz( GetOutputSizePixel() ); + const int nEntryCount = mpImpl->maEntryVector.size(); + int nEntry; + for( nEntry = 0; nEntry < nEntryCount; nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry]; + + Point aPos( aTopLeft ); + aPos.Y() += nBorder; + aPos.Y() += nStartY; + + + if( (pEntry == 0) && !pThisOnly ) + { + // Separator + aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT-2)/2); + aTmpPos.X() = aPos.X() + 2 + nOuterSpace; + SetLineColor( rSettings.GetShadowColor() ); + DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); + aTmpPos.Y()++; + SetLineColor( rSettings.GetLightColor() ); + DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) ); + SetLineColor(); + } + else if( !pThisOnly || ( pEntry == pThisOnly ) ) + { + const bool bTitle = pEntry->mnEntryId == TITLE_ID; + + if ( pThisOnly && bHighlighted ) + SetTextColor( rSettings.GetMenuHighlightTextColor() ); + + if( aPos.Y() >= 0 ) + { + long nTextOffsetY = ((pEntry->maSize.Height()-nFontHeight)/2); + + USHORT nTextStyle = 0; + USHORT nSymbolStyle = 0; + USHORT nImageStyle = 0; + + if( !pEntry->mbEnabled ) + { + nTextStyle |= TEXT_DRAW_DISABLE; + nSymbolStyle |= SYMBOL_DRAW_DISABLE; + nImageStyle |= IMAGE_DRAW_DISABLE; + } + + Rectangle aOuterCheckRect( Point( aPos.X()+mpImpl->mnCheckPos, aPos.Y() ), Size( pEntry->maSize.Height(), pEntry->maSize.Height() ) ); + aOuterCheckRect.Left() += 1; + aOuterCheckRect.Right() -= 1; + aOuterCheckRect.Top() += 1; + aOuterCheckRect.Bottom() -= 1; + + if( bTitle ) + { + // fill the background + Rectangle aRect( aTopLeft, Size( aOutSz.Width(), pEntry->maSize.Height() ) ); + SetFillColor(rSettings.GetDialogColor()); + SetLineColor(); + DrawRect(aRect); + SetLineColor( rSettings.GetLightColor() ); + DrawLine( aRect.TopLeft(), aRect.TopRight() ); + SetLineColor( rSettings.GetShadowColor() ); + DrawLine( aRect.BottomLeft(), aRect.BottomRight() ); + } + + // CheckMark + if ( pEntry->HasCheck() ) + { + // draw selection transparent marker if checked + // onto that either a checkmark or the item image + // will be painted + // however do not do this if native checks will be painted since + // the selection color too often does not fit the theme's check and/or radio + + if( !pEntry->mbHasImage ) + { + if( this->IsNativeControlSupported( CTRL_MENU_POPUP, + (pEntry->mnBits & MIB_RADIOCHECK) + ? PART_MENU_ITEM_CHECK_MARK + : PART_MENU_ITEM_RADIO_MARK ) ) + { + ControlPart nPart = ((pEntry->mnBits & MIB_RADIOCHECK) + ? PART_MENU_ITEM_RADIO_MARK + : PART_MENU_ITEM_CHECK_MARK); + + ControlState nState = 0; + + if ( pEntry->mbChecked ) + nState |= CTRL_STATE_PRESSED; + + if ( pEntry->mbEnabled ) + nState |= CTRL_STATE_ENABLED; + + if ( bHighlighted ) + nState |= CTRL_STATE_SELECTED; + + long nCtrlHeight = (pEntry->mnBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight; + aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight)/2; + aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2; + + Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) ); + DrawNativeControl( CTRL_MENU_POPUP, nPart, Region( aCheckRect ), nState, ImplControlValue(), OUString() ); + } + else if ( pEntry->mbChecked ) // by default do nothing for unchecked items + { + ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted ); + + SymbolType eSymbol; + Size aSymbolSize; + if ( pEntry->mnBits & MIB_RADIOCHECK ) + { + eSymbol = SYMBOL_RADIOCHECKMARK; + aSymbolSize = Size( nFontHeight/2, nFontHeight/2 ); + } + else + { + eSymbol = SYMBOL_CHECKMARK; + aSymbolSize = Size( (nFontHeight*25)/40, nFontHeight/2 ); + } + aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2; + aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2; + Rectangle aRect( aTmpPos, aSymbolSize ); + aDecoView.DrawSymbol( aRect, eSymbol, GetTextColor(), nSymbolStyle ); + } + } + } + + // Image: + if( pEntry->mbHasImage && bUseImages ) + { + // Don't render an image for a check thing + /* if((nMenuFlags & MENU_FLAG_SHOWCHECKIMAGES) || !pEntry->HasCheck() )*/ + { + if( pEntry->mbChecked ) + ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted ); + aTmpPos = aOuterCheckRect.TopLeft(); + aTmpPos.X() += (aOuterCheckRect.GetWidth()-pEntry->maImage.GetSizePixel().Width())/2; + aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pEntry->maImage.GetSizePixel().Height())/2; + DrawImage( aTmpPos, pEntry->maImage, nImageStyle ); + } + } + + // Text: + if( pEntry->mbHasText ) + { + aTmpPos.X() = aPos.X() + (bTitle ? 4 : mpImpl->mnTextPos); + aTmpPos.Y() = aPos.Y(); + aTmpPos.Y() += nTextOffsetY; + USHORT nStyle = nTextStyle|TEXT_DRAW_MNEMONIC; + + DrawCtrlText( aTmpPos, pEntry->maText, 0, pEntry->maText.Len(), nStyle, NULL, NULL ); // pVector, pDisplayText ); + } + +/* + // Accel + if ( !bLayout && !bIsMenuBar && pData->aAccelKey.GetCode() && !ImplAccelDisabled() ) + { + XubString aAccText = pData->aAccelKey.GetName(); + aTmpPos.X() = aOutSz.Width() - this->GetTextWidth( aAccText ); + aTmpPos.X() -= 4*nExtra; + + aTmpPos.X() -= nOuterSpace; + aTmpPos.Y() = aPos.Y(); + aTmpPos.Y() += nTextOffsetY; + this->DrawCtrlText( aTmpPos, aAccText, 0, aAccText.Len(), nTextStyle ); + } +*/ + +/* + // SubMenu? + if ( !bLayout && !bIsMenuBar && pData->pSubMenu ) + { + aTmpPos.X() = aOutSz.Width() - nFontHeight + nExtra - nOuterSpace; + aTmpPos.Y() = aPos.Y(); + aTmpPos.Y() += nExtra/2; + aTmpPos.Y() += ( pEntry->maSize.Height() / 2 ) - ( nFontHeight/4 ); + if ( pEntry->mnBits & MIB_POPUPSELECT ) + { + this->SetTextColor( rSettings.GetMenuTextColor() ); + Point aTmpPos2( aPos ); + aTmpPos2.X() = aOutSz.Width() - nFontHeight - nFontHeight/4; + aDecoView.DrawFrame( + Rectangle( aTmpPos2, Size( nFontHeight+nFontHeight/4, pEntry->maSize.Height() ) ), FRAME_DRAW_GROUP ); + } + aDecoView.DrawSymbol( + Rectangle( aTmpPos, Size( nFontHeight/2, nFontHeight/2 ) ), + SYMBOL_SPIN_RIGHT, this->GetTextColor(), nSymbolStyle ); +// if ( pEntry->mnBits & MIB_POPUPSELECT ) +// { +// aTmpPos.Y() += nFontHeight/2 ; +// this->SetLineColor( rSettings.GetShadowColor() ); +// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) ); +// this->SetLineColor( rSettings.GetLightColor() ); +// aTmpPos.Y()++; +// this->DrawLine( aTmpPos, Point( aTmpPos.X() + nFontHeight/3, aTmpPos.Y() ) ); +// this->SetLineColor(); +// } + } +*/ + + if ( pThisOnly && bHighlighted ) + { + // This restores the normal menu or menu bar text + // color for when it is no longer highlighted. + SetTextColor( rSettings.GetMenuTextColor() ); + } + } + } + + aTopLeft.Y() += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT; + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::Paint( const Rectangle& ) +{ + SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() ); + + implPaint(); + + if( mpImpl->mnHighlightedEntry != -1 ) + implHighlightEntry( mpImpl->mnHighlightedEntry, true ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt ) +{ + DockingWindow::RequestHelp( rHEvt ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::StateChanged( StateChangedType nType ) +{ + DockingWindow::StateChanged( nType ); + + if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) ) + { + initWindow(); + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt ) +{ + DockingWindow::DataChanged( rDCEvt ); + + if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || + (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || + ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && + (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) + { + initWindow(); + Invalidate(); + } +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::Command( const CommandEvent& rCEvt ) +{ + if ( rCEvt.GetCommand() == COMMAND_WHEEL ) + { + const CommandWheelData* pData = rCEvt.GetWheelData(); + if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) ) + { + implCursorUpDown( pData->GetDelta() > 0L, false ); + } + } +} + +// -------------------------------------------------------------------- + +Reference< ::com::sun::star::accessibility::XAccessible > ToolbarMenu::CreateAccessible() +{ + mpImpl->setAccessible( new ToolbarMenuAcc( *mpImpl ) ); + return Reference< XAccessible >( mpImpl->mxAccessible.get() ); +} + +// -------------------------------------------------------------------- + +// todo: move to new base class that will replace SfxPopupWindo +void ToolbarMenu::AddStatusListener( const rtl::OUString& rCommandURL ) +{ + initStatusListener(); + mpImpl->mxStatusListener->addStatusListener( rCommandURL ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::RemoveStatusListener( const rtl::OUString& rCommandURL ) +{ + mpImpl->mxStatusListener->removeStatusListener( rCommandURL ); +} +// -------------------------------------------------------------------- + + +void ToolbarMenu::UpdateStatus( const rtl::OUString& rCommandURL ) +{ + mpImpl->mxStatusListener->updateStatus( rCommandURL ); +} + +// -------------------------------------------------------------------- + +// XStatusListener (subclasses must override this one to get the status updates +void SAL_CALL ToolbarMenu::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& /*Event*/ ) throw ( ::com::sun::star::uno::RuntimeException ) +{ +} + +// -------------------------------------------------------------------- + +class ToolbarMenuStatusListener : public svt::FrameStatusListener +{ +public: + ToolbarMenuStatusListener( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame, + ToolbarMenu& rToolbarMenu ); + + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException ); + + ToolbarMenu* mpMenu; +}; + +// -------------------------------------------------------------------- + +ToolbarMenuStatusListener::ToolbarMenuStatusListener( + const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame, + ToolbarMenu& rToolbarMenu ) +: svt::FrameStatusListener( xServiceManager, xFrame ) +, mpMenu( &rToolbarMenu ) +{ +} + +// -------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuStatusListener::dispose() throw (::com::sun::star::uno::RuntimeException) +{ + mpMenu = 0; + svt::FrameStatusListener::dispose(); +} + +// -------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuStatusListener::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException ) +{ + if( mpMenu ) + mpMenu->statusChanged( Event ); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::initStatusListener() +{ + if( !mpImpl->mxStatusListener.is() ) + mpImpl->mxStatusListener.set( new ToolbarMenuStatusListener( mpImpl->mxServiceManager, mpImpl->mxFrame, *this ) ); +} + +// -------------------------------------------------------------------- + +bool ToolbarMenu::IsInPopupMode() +{ + return GetDockingManager()->IsInPopupMode(this); +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::EndPopupMode() +{ + GetDockingManager()->EndPopupMode(this); +} + +// -------------------------------------------------------------------- + +const Size& ToolbarMenu::getMenuSize() const +{ + return mpImpl->maSize; +} + +// -------------------------------------------------------------------- + +void ToolbarMenu::SetSelectHdl( const Link& rLink ) +{ + mpImpl->maSelectHdl = rLink; +} + +// -------------------------------------------------------------------- + +const Link& ToolbarMenu::GetSelectHdl() const +{ + return mpImpl->maSelectHdl; +} + +// -------------------------------------------------------------------- + +Reference< XFrame > ToolbarMenu::GetFrame() const +{ + return mpImpl->mxFrame; +} + +// -------------------------------------------------------------------- + + +// -------------------------------------------------------------------- + +} + + diff --git a/svtools/source/control/toolbarmenuacc.cxx b/svtools/source/control/toolbarmenuacc.cxx new file mode 100644 index 000000000000..020467084748 --- /dev/null +++ b/svtools/source/control/toolbarmenuacc.cxx @@ -0,0 +1,1003 @@ +/************************************************************************* + * + * 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_svtools.hxx" + +#include <com/sun/star/accessibility/AccessibleEventId.hpp> +#include <com/sun/star/accessibility/AccessibleRole.hpp> +#include <com/sun/star/accessibility/AccessibleStateType.hpp> + +#include <unotools/accessiblestatesethelper.hxx> + +#include <vcl/svapp.hxx> + +#include "svtools/toolbarmenu.hxx" + +#include "toolbarmenuimp.hxx" + +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::accessibility; + +namespace svtools { + +// ------------------ +// - ToolbarMenuAcc - +// ------------------ + +ToolbarMenuAcc::ToolbarMenuAcc( ToolbarMenu_Impl& rParent ) +: ToolbarMenuAccComponentBase(m_aMutex) +, mpParent( &rParent ) +, mbIsFocused(false) +{ + mpParent->mrMenu.AddEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) ); +} + +// ----------------------------------------------------------------------------- + +ToolbarMenuAcc::~ToolbarMenuAcc() +{ + if( mpParent ) + mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) ); +} + +// ----------------------------------------------------------------------- + +IMPL_LINK( ToolbarMenuAcc, WindowEventListener, VclSimpleEvent*, pEvent ) +{ + DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" ); + + /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper + * might have been destroyed by the previous VCLEventListener (if no AT tool + * is running), e.g. sub-toolbars in impress. + */ + if ( mpParent && pEvent && pEvent->ISA( VclWindowEvent ) && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) ) + { + DBG_ASSERT( ((VclWindowEvent*)pEvent)->GetWindow(), "Window???" ); + if( !((VclWindowEvent*)pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) ) + { + ProcessWindowEvent( *(VclWindowEvent*)pEvent ); + } + } + return 0; +} + +// ----------------------------------------------------------------------- + +void ToolbarMenuAcc::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ) +{ + Any aOldValue, aNewValue; + + switch ( rVclWindowEvent.GetId() ) + { + case VCLEVENT_OBJECT_DYING: + { + mpParent->mrMenu.RemoveEventListener( LINK( this, ToolbarMenuAcc, WindowEventListener ) ); + mpParent = 0; + } + break; + + case VCLEVENT_WINDOW_GETFOCUS: + { + if( !mbIsFocused ) + { + mpParent->notifyHighlightedEntry(); + mbIsFocused = true; + } + } + break; + case VCLEVENT_WINDOW_LOSEFOCUS: + { + if( mbIsFocused ) + { + mbIsFocused = false; + } + } + break; + default: + { + } + break; + } +} + +// ----------------------------------------------------------------------- + +void ToolbarMenuAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue ) +{ + if( nEventId ) + { + EventListenerVector aTmpListeners( mxEventListeners ); + EventListenerVector::const_iterator aIter( aTmpListeners.begin() ); + AccessibleEventObject aEvtObject; + + aEvtObject.EventId = nEventId; + aEvtObject.Source = static_cast<XWeak*>(this); + aEvtObject.NewValue = rNewValue; + aEvtObject.OldValue = rOldValue; + + while( aIter != aTmpListeners.end() ) + { + try + { + (*aIter)->notifyEvent( aEvtObject ); + } + catch( Exception& ) + { + } + + aIter++; + } + } +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessibleContext > SAL_CALL ToolbarMenuAcc::getAccessibleContext() throw (RuntimeException) +{ + ThrowIfDisposed(); + return this; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleChildCount() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + return mpParent->getAccessibleChildCount(); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleChild( sal_Int32 i ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + return mpParent->getAccessibleChild(i); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleParent() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + Reference< XAccessible > xRet; + + Window* pParent = mpParent->mrMenu.GetParent(); + if( pParent ) + xRet = pParent->GetAccessible(); + + return xRet; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuAcc::getAccessibleIndexInParent() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + Window* pParent = mpParent->mrMenu.GetParent(); + if( pParent ) + { + for( USHORT i = 0, nCount = pParent->GetChildCount(); i < nCount ; i++ ) + { + if( pParent->GetChild( i ) == &mpParent->mrMenu ) + return i; + } + } + + return 0; +} + +// ----------------------------------------------------------------------------- + +sal_Int16 SAL_CALL ToolbarMenuAcc::getAccessibleRole() throw (RuntimeException) +{ + ThrowIfDisposed(); + return AccessibleRole::LIST; +} + +// ----------------------------------------------------------------------------- + +OUString SAL_CALL ToolbarMenuAcc::getAccessibleDescription() throw (RuntimeException) +{ + ThrowIfDisposed(); + return OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolbarMenu" ) ); +} + +// ----------------------------------------------------------------------------- + +OUString SAL_CALL ToolbarMenuAcc::getAccessibleName() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + OUString aRet; + + if( mpParent ) + aRet = mpParent->mrMenu.GetAccessibleName(); + + if( !aRet.getLength() ) + { + Window* pLabel = mpParent->mrMenu.GetLabeledBy(); + if( pLabel && pLabel != &mpParent->mrMenu ) + aRet = OutputDevice::GetNonMnemonicString( pLabel->GetText() ); + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuAcc::getAccessibleRelationSet() throw (RuntimeException) +{ + ThrowIfDisposed(); + return Reference< XAccessibleRelationSet >(); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuAcc::getAccessibleStateSet() throw (RuntimeException) +{ + ThrowIfDisposed(); + ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper(); + + // Set some states. + pStateSet->AddState (AccessibleStateType::ENABLED); + pStateSet->AddState (AccessibleStateType::SENSITIVE); + pStateSet->AddState (AccessibleStateType::SHOWING); + pStateSet->AddState (AccessibleStateType::VISIBLE); + pStateSet->AddState (AccessibleStateType::MANAGES_DESCENDANTS); + pStateSet->AddState (AccessibleStateType::FOCUSABLE); + if (mbIsFocused) + pStateSet->AddState (AccessibleStateType::FOCUSED); + + return pStateSet; +} + +// ----------------------------------------------------------------------------- + +Locale SAL_CALL ToolbarMenuAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + const ::rtl::OUString aEmptyStr; + Reference< XAccessible > xParent( getAccessibleParent() ); + Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr ); + + if( xParent.is() ) + { + Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + + if( xParentContext.is() ) + aRet = xParentContext->getLocale (); + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard(m_aMutex); + + if( rxListener.is() ) + { + EventListenerVector::const_iterator aIter = mxEventListeners.begin(); + bool bFound = false; + + while( !bFound && ( aIter != mxEventListeners.end() ) ) + { + if( *aIter == rxListener ) + bFound = true; + else + aIter++; + } + + if (!bFound) + mxEventListeners.push_back( rxListener ); + } +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard(m_aMutex); + + if( rxListener.is() ) + { + EventListenerVector::iterator aIter = mxEventListeners.begin(); + bool bFound = false; + + while( !bFound && ( aIter != mxEventListeners.end() ) ) + { + if( *aIter == rxListener ) + { + mxEventListeners.erase( aIter ); + bFound = true; + } + else + aIter++; + } + } +} + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL ToolbarMenuAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException) +{ + ThrowIfDisposed(); + const awt::Rectangle aRect( getBounds() ); + const Point aSize( aRect.Width, aRect.Height ); + const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y ); + + return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint ); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getAccessibleAtPoint( const awt::Point& aPoint ) throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + Reference< XAccessible > xRet; + + const Point aVclPoint( aPoint.X, aPoint.Y ); + + const int nEntryCount = mpParent->maEntryVector.size(); + for( int nEntry = 0; (nEntry < nEntryCount) && !xRet.is(); nEntry++ ) + { + ToolbarMenuEntry* pEntry = mpParent->maEntryVector[nEntry]; + if( pEntry && pEntry->maRect.IsInside( aVclPoint ) ) + { + if( pEntry->mpControl ) + { + awt::Point aChildPoint( aPoint.X - pEntry->maRect.Left(), aPoint.Y - pEntry->maRect.Top() ); + Reference< XAccessibleComponent > xComp( pEntry->GetAccessible(true), UNO_QUERY_THROW ); + xRet = xComp->getAccessibleAtPoint(aChildPoint); + } + else + { + xRet = Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY ); + } + } + } + return xRet; +} + +// ----------------------------------------------------------------------------- + +awt::Rectangle SAL_CALL ToolbarMenuAcc::getBounds() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + const Point aOutPos( mpParent->mrMenu.GetPosPixel() ); + const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() ); + awt::Rectangle aRet; + + aRet.X = aOutPos.X(); + aRet.Y = aOutPos.Y(); + aRet.Width = aOutSize.Width(); + aRet.Height = aOutSize.Height(); + + return aRet; +} + +// ----------------------------------------------------------------------------- + +awt::Point SAL_CALL ToolbarMenuAcc::getLocation() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + const Point aOutPos( mpParent->mrMenu.GetPosPixel() ); + return awt::Point( aOutPos.X(), aOutPos.Y() ); +} + +// ----------------------------------------------------------------------------- + +awt::Point SAL_CALL ToolbarMenuAcc::getLocationOnScreen() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( Point() ) ); + return awt::Point( aScreenPos.X(), aScreenPos.Y() ); +} + +// ----------------------------------------------------------------------------- + +awt::Size SAL_CALL ToolbarMenuAcc::getSize() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + const Size aOutSize( mpParent->mrMenu.GetOutputSizePixel() ); + return awt::Size( aOutSize.Width(), aOutSize.Height() ); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::grabFocus() throw (RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + mpParent->mrMenu.GrabFocus(); +} + +// ----------------------------------------------------------------------------- + +Any SAL_CALL ToolbarMenuAcc::getAccessibleKeyBinding() throw (RuntimeException) +{ + ThrowIfDisposed(); + return Any(); +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuAcc::getForeground() throw (RuntimeException) +{ + ThrowIfDisposed(); + UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor(); + return static_cast<sal_Int32>(nColor); +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuAcc::getBackground() throw (RuntimeException) +{ + ThrowIfDisposed(); + UINT32 nColor = Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor(); + return static_cast<sal_Int32>(nColor); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + mpParent->selectAccessibleChild( nChildIndex ); +} + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL ToolbarMenuAcc::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + return mpParent->isAccessibleChildSelected( nChildIndex ); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::clearAccessibleSelection() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + mpParent->clearAccessibleSelection(); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::selectAllAccessibleChildren() throw (RuntimeException) +{ + ThrowIfDisposed(); + // unsupported due to single selection only +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChildCount() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ThrowIfDisposed(); + + return mpParent->mnHighlightedEntry != -1 ? 1 : 0; +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuAcc::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + + if( (mpParent->mnHighlightedEntry != -1) && (nSelectedChildIndex == 0) ) + { + ToolbarMenuEntry* pEntry = mpParent->maEntryVector[ mpParent->mnHighlightedEntry ]; + if( pEntry ) + { + if( pEntry->mpControl ) + { + Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW ); + return xSel->getSelectedAccessibleChild(0); + } + else + return Reference< XAccessible >( pEntry->GetAccessible(true), UNO_QUERY ); + } + } + + throw IndexOutOfBoundsException(); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::deselectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException) +{ + ThrowIfDisposed(); + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // Because of the single selection we can reset the whole selection when + // the specified child is currently selected. + if (isAccessibleChildSelected(nChildIndex)) + mpParent->clearAccessibleSelection(); +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuAcc::disposing (void) +{ + EventListenerVector aListenerListCopy; + + { + // Make a copy of the list and clear the original. + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard (m_aMutex); + aListenerListCopy = mxEventListeners; + mxEventListeners.clear(); + + // Reset the pointer to the parent. It has to be the one who has + // disposed us because he is dying. + mpParent = NULL; + } + + // Inform all listeners that this objects is disposing. + EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin()); + EventObject aEvent (static_cast<XAccessible*>(this)); + while(aListenerIterator != aListenerListCopy.end()) + { + try + { + (*aListenerIterator)->disposing (aEvent); + } + catch( Exception& ) + { + // Ignore exceptions. + } + + ++aListenerIterator; + } +} + +void ToolbarMenuAcc::ThrowIfDisposed (void) throw (DisposedException) +{ + if(rBHelper.bDisposed || rBHelper.bInDispose || !mpParent) + { + throw DisposedException ( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), static_cast<XWeak*>(this)); + } +} + +// ----------------------- +// - ToolbarMenuEntryAcc - +// ----------------------- + +ToolbarMenuEntryAcc::ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent ) +: ToolbarMenuEntryAccBase( m_aMutex ) +, mpParent( pParent ) +{ +} + +// ----------------------------------------------------------------------------- + +ToolbarMenuEntryAcc::~ToolbarMenuEntryAcc() +{ +} + +// ----------------------------------------------------------------------- + +void ToolbarMenuEntryAcc::FireAccessibleEvent( short nEventId, const Any& rOldValue, const Any& rNewValue ) +{ + if( nEventId ) + { + EventListenerVector aTmpListeners( mxEventListeners ); + ::std::vector< Reference< XAccessibleEventListener > >::const_iterator aIter( aTmpListeners.begin() ); + AccessibleEventObject aEvtObject; + + aEvtObject.EventId = nEventId; + aEvtObject.Source = static_cast<XWeak*>(this); + aEvtObject.NewValue = rNewValue; + aEvtObject.OldValue = rOldValue; + + while( aIter != aTmpListeners.end() ) + { + (*aIter)->notifyEvent( aEvtObject ); + aIter++; + } + } +} + + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuEntryAcc::disposing (void) +{ + EventListenerVector aListenerListCopy; + + { + // Make a copy of the list and clear the original. + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::osl::MutexGuard aGuard (m_aMutex); + aListenerListCopy = mxEventListeners; + mxEventListeners.clear(); + + // Reset the pointer to the parent. It has to be the one who has + // disposed us because he is dying. + mpParent = NULL; + } + + // Inform all listeners that this objects is disposing. + EventListenerVector::const_iterator aListenerIterator (aListenerListCopy.begin()); + EventObject aEvent (static_cast<XAccessible*>(this)); + while(aListenerIterator != aListenerListCopy.end()) + { + try + { + (*aListenerIterator)->disposing (aEvent); + } + catch( Exception& ) + { + // Ignore exceptions. + } + + ++aListenerIterator; + } +} +// ----------------------------------------------------------------------------- + +Reference< XAccessibleContext > SAL_CALL ToolbarMenuEntryAcc::getAccessibleContext() throw (RuntimeException) +{ + return this; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleChildCount() throw (RuntimeException) +{ + return 0; +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleChild( sal_Int32 ) throw (IndexOutOfBoundsException, RuntimeException) +{ + throw IndexOutOfBoundsException(); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleParent() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + Reference< XAccessible > xRet; + + if( mpParent ) + xRet = mpParent->mrMenu.GetAccessible(); + + return xRet; +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getAccessibleIndexInParent() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // The index defaults to -1 to indicate the child does not belong to its + // parent. + sal_Int32 nIndexInParent = -1; + + if( mpParent ) + { + Reference< XAccessibleContext > xParent( mpParent->mrMenu.GetAccessible(), UNO_QUERY ); + + if( xParent.is() ) + { + Reference< XAccessible > xThis( this ); + + const sal_Int32 nCount = xParent->getAccessibleChildCount(); + for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) + { + if( xParent->getAccessibleChild(nIndex) == xThis ) + { + nIndexInParent = nIndex; + break; + } + } + } + } + + return nIndexInParent; +} + +// ----------------------------------------------------------------------------- + +sal_Int16 SAL_CALL ToolbarMenuEntryAcc::getAccessibleRole() throw (RuntimeException) +{ + return AccessibleRole::LIST_ITEM; +} + +// ----------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleDescription() throw (RuntimeException) +{ + return ::rtl::OUString(); +} + +// ----------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL ToolbarMenuEntryAcc::getAccessibleName() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + String aRet; + + if( mpParent ) + { + aRet = mpParent->maText; + + if( !aRet.Len() ) + { + aRet = String( RTL_CONSTASCII_USTRINGPARAM( "Item " ) ); + aRet += String::CreateFromInt32( mpParent->mnEntryId ); + } + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessibleRelationSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleRelationSet() throw (RuntimeException) +{ + return Reference< XAccessibleRelationSet >(); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessibleStateSet > SAL_CALL ToolbarMenuEntryAcc::getAccessibleStateSet() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper; + + if( mpParent ) + { + pStateSet->AddState (AccessibleStateType::ENABLED); + pStateSet->AddState (AccessibleStateType::SENSITIVE); + pStateSet->AddState (AccessibleStateType::SHOWING); + pStateSet->AddState (AccessibleStateType::VISIBLE); + pStateSet->AddState (AccessibleStateType::TRANSIENT); + if( mpParent->mnEntryId != TITLE_ID ) + { + pStateSet->AddState( AccessibleStateType::SELECTABLE ); + + // SELECTED + if( mpParent->mrMenu.getHighlightedEntryId() == mpParent->mnEntryId ) + pStateSet->AddState( AccessibleStateType::SELECTED ); + } + } + + return pStateSet; +} + +// ----------------------------------------------------------------------------- + +Locale SAL_CALL ToolbarMenuEntryAcc::getLocale() throw (IllegalAccessibleComponentStateException, RuntimeException) +{ + const ::rtl::OUString aEmptyStr; + Locale aRet( aEmptyStr, aEmptyStr, aEmptyStr ); + + Reference< XAccessible > xParent( getAccessibleParent() ); + if( xParent.is() ) + { + Reference< XAccessibleContext > xParentContext( xParent->getAccessibleContext() ); + + if( xParentContext.is() ) + aRet = xParentContext->getLocale(); + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuEntryAcc::addEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException) +{ + const ::vos::OGuard aGuard( maMutex ); + + if( rxListener.is() ) + { + EventListenerVector::const_iterator aIter( mxEventListeners.begin() ); + bool bFound = false; + + while( !bFound && ( aIter != mxEventListeners.end() ) ) + { + if( *aIter == rxListener ) + bFound = true; + else + aIter++; + } + + if (!bFound) + mxEventListeners.push_back( rxListener ); + } +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuEntryAcc::removeEventListener( const Reference< XAccessibleEventListener >& rxListener ) throw (RuntimeException) +{ + const ::vos::OGuard aGuard( maMutex ); + + if( rxListener.is() ) + { + EventListenerVector::iterator aIter = mxEventListeners.begin(); + bool bFound = false; + + while( !bFound && ( aIter != mxEventListeners.end() ) ) + { + if( *aIter == rxListener ) + { + mxEventListeners.erase( aIter ); + bFound = true; + } + else + aIter++; + } + } +} + +// ----------------------------------------------------------------------------- + +sal_Bool SAL_CALL ToolbarMenuEntryAcc::containsPoint( const awt::Point& aPoint ) throw (RuntimeException) +{ + const awt::Rectangle aRect( getBounds() ); + const Point aSize( aRect.Width, aRect.Height ); + const Point aNullPoint, aTestPoint( aPoint.X, aPoint.Y ); + + return Rectangle( aNullPoint, aSize ).IsInside( aTestPoint ); +} + +// ----------------------------------------------------------------------------- + +Reference< XAccessible > SAL_CALL ToolbarMenuEntryAcc::getAccessibleAtPoint( const awt::Point& ) throw (RuntimeException) +{ + Reference< XAccessible > xRet; + return xRet; +} + +// ----------------------------------------------------------------------------- + +awt::Rectangle SAL_CALL ToolbarMenuEntryAcc::getBounds() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + awt::Rectangle aRet; + + if( mpParent ) + { + Rectangle aRect( mpParent->maRect ); + Point aOrigin; + Rectangle aParentRect( aOrigin, mpParent->mrMenu.GetOutputSizePixel() ); + + aRect.Intersection( aParentRect ); + + aRet.X = aRect.Left(); + aRet.Y = aRect.Top(); + aRet.Width = aRect.GetWidth(); + aRet.Height = aRect.GetHeight(); + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocation() throw (RuntimeException) +{ + const awt::Rectangle aRect( getBounds() ); + return awt::Point( aRect.X, aRect.Y ); +} + +// ----------------------------------------------------------------------------- + +awt::Point SAL_CALL ToolbarMenuEntryAcc::getLocationOnScreen() throw (RuntimeException) +{ + const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + awt::Point aRet; + + if( mpParent ) + { + const Point aScreenPos( mpParent->mrMenu.OutputToAbsoluteScreenPixel( mpParent->maRect.TopLeft() ) ); + + aRet.X = aScreenPos.X(); + aRet.Y = aScreenPos.Y(); + } + + return aRet; +} + +// ----------------------------------------------------------------------------- + +awt::Size SAL_CALL ToolbarMenuEntryAcc::getSize() throw (RuntimeException) +{ + const awt::Rectangle aRect( getBounds() ); + awt::Size aRet; + + aRet.Width = aRect.Width; + aRet.Height = aRect.Height; + + return aRet; +} + +// ----------------------------------------------------------------------------- + +void SAL_CALL ToolbarMenuEntryAcc::grabFocus() throw (RuntimeException) +{ + // nothing to do +} + +// ----------------------------------------------------------------------------- + +Any SAL_CALL ToolbarMenuEntryAcc::getAccessibleKeyBinding() throw (RuntimeException) +{ + return Any(); +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getForeground( ) throw (RuntimeException) +{ + return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuTextColor().GetColor()); +} + +// ----------------------------------------------------------------------------- + +sal_Int32 SAL_CALL ToolbarMenuEntryAcc::getBackground( ) throw (RuntimeException) +{ + return static_cast<sal_Int32>(Application::GetSettings().GetStyleSettings().GetMenuColor().GetColor()); +} + +} diff --git a/svtools/source/control/toolbarmenuimp.hxx b/svtools/source/control/toolbarmenuimp.hxx new file mode 100644 index 000000000000..d1de4f704b76 --- /dev/null +++ b/svtools/source/control/toolbarmenuimp.hxx @@ -0,0 +1,314 @@ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include <vos/mutex.hxx> +#include <vcl/image.hxx> +#include <vcl/menu.hxx> + +#include <cppuhelper/compbase4.hxx> +#include <cppuhelper/compbase5.hxx> +#include <comphelper/broadcasthelper.hxx> + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/accessibility/XAccessible.hpp> +#include <com/sun/star/accessibility/XAccessibleContext.hpp> +#include <com/sun/star/accessibility/XAccessibleComponent.hpp> +#include <com/sun/star/accessibility/XAccessibleSelection.hpp> +#include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +#include <rtl/ref.hxx> + +#include <vector> + +#include "framestatuslistener.hxx" + +#include "svtools/valueset.hxx" + +namespace svtools { + +struct ToolbarMenu_Impl; +class ToolbarMenu; +class ToolbarMenuEntry; + +typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener > > EventListenerVector; +typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector; + +const int EXTRAITEMHEIGHT = 0; // 4; +const int SEPARATOR_HEIGHT = 4; +const int TITLE_ID = -1; +const int BORDER_X = 0; +const int BORDER_Y = 0; + +// -------------------- +// - ToolbarMenuEntry - +// -------------------- + +class ToolbarMenuEntry +{ +public: + ToolbarMenu& mrMenu; + + int mnEntryId; + MenuItemBits mnBits; + Size maSize; + + bool mbHasText; + bool mbHasImage; + bool mbChecked; + bool mbEnabled; + + String maText; + Image maImage; + Control* mpControl; + Rectangle maRect; + + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > mxAccContext; + +public: + ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits ); + ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits ); + ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits ); + ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits ); + ~ToolbarMenuEntry(); + + void init( int nEntryId, MenuItemBits nBits ); + + const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& GetAccessible( bool bCreate = false ); + + sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + bool HasCheck() const + { + return mbChecked || ( mnBits & ( MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK ) ); + } +}; + +// --------------- +// - ToolbarMenuAcc - +// --------------- + +typedef ::cppu::WeakComponentImplHelper5< + ::com::sun::star::accessibility::XAccessible, + ::com::sun::star::accessibility::XAccessibleEventBroadcaster, + ::com::sun::star::accessibility::XAccessibleContext, + ::com::sun::star::accessibility::XAccessibleComponent, + ::com::sun::star::accessibility::XAccessibleSelection > + ToolbarMenuAccComponentBase; + +class ToolbarMenuAcc : + public ::comphelper::OBaseMutex, + public ToolbarMenuAccComponentBase +{ +public: + + ToolbarMenuAcc( ToolbarMenu_Impl& rParent ); + ~ToolbarMenuAcc(); + + void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); + bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); } + +public: + // XAccessible + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::addEventListener; + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::removeEventListener; + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleSelection + virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + DECL_LINK( WindowEventListener, VclSimpleEvent* ); + +private: + EventListenerVector mxEventListeners; + ToolbarMenu_Impl* mpParent; + /// The current FOCUSED state. + bool mbIsFocused; + + void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); + + /** Tell all listeners that the object is dying. This callback is + usually called from the WeakComponentImplHelper class. + */ + virtual void SAL_CALL disposing (void); + + /** Check whether or not the object has been disposed (or is in the + state of beeing disposed). If that is the case then + DisposedException is thrown to inform the (indirect) caller of the + foul deed. + */ + void ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException); +}; + +// ----------------------- +// - ToolbarMenuEntryAcc - +// ----------------------- + +typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::accessibility::XAccessible, + ::com::sun::star::accessibility::XAccessibleEventBroadcaster, + ::com::sun::star::accessibility::XAccessibleContext, + ::com::sun::star::accessibility::XAccessibleComponent > ToolbarMenuEntryAccBase; + +class ToolbarMenuEntryAcc : public ::comphelper::OBaseMutex, + public ToolbarMenuEntryAccBase +{ +public: + ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent ); + ~ToolbarMenuEntryAcc(); + + void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); + bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); } + + // XAccessible + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleEventBroadcaster + using ToolbarMenuEntryAccBase::addEventListener; + virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + using ToolbarMenuEntryAccBase::removeEventListener; + virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); + + // XAccessibleContext + virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); + + // XAccessibleComponent + virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException); + +private: + EventListenerVector mxEventListeners; + ::vos::OMutex maMutex; + ToolbarMenuEntry* mpParent; + + /** Tell all listeners that the object is dying. This callback is + usually called from the WeakComponentImplHelper class. + */ + virtual void SAL_CALL disposing (void); +}; + +// ----------------------------------------------------------------------------- + +struct ToolbarMenu_Impl +{ + ToolbarMenu& mrMenu; + + ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame; + rtl::Reference< svt::FrameStatusListener > mxStatusListener; + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxServiceManager; + rtl::Reference< ToolbarMenuAcc > mxAccessible; + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxOldSelection; + + ToolbarMenuEntryVector maEntryVector; + + int mnCheckPos; + int mnImagePos; + int mnTextPos; + + int mnHighlightedEntry; + int mnSelectedEntry; + int mnLastColumn; + + Size maSize; + + Link maSelectHdl; + + ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame ); + ~ToolbarMenu_Impl(); + + void setAccessible( ToolbarMenuAcc* pAccessible ); + + void fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); + bool hasAccessibleListeners(); + + sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + + void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + sal_Bool isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); + void clearAccessibleSelection(); + + ToolbarMenuEntry* implGetEntry( int nEntry ) const; + void notifyHighlightedEntry(); + + void implHighlightControl( USHORT nCode, Control* pControl ); +}; + +} diff --git a/svtools/source/control/valueacc.cxx b/svtools/source/control/valueacc.cxx index 6712e75aa9b4..66da5636d89c 100644 --- a/svtools/source/control/valueacc.cxx +++ b/svtools/source/control/valueacc.cxx @@ -976,10 +976,7 @@ sal_Int16 SAL_CALL ValueItemAcc::getAccessibleRole() ::rtl::OUString SAL_CALL ValueItemAcc::getAccessibleDescription() throw (uno::RuntimeException) { - const vos::OGuard aSolarGuard( Application::GetSolarMutex() ); - String aRet( RTL_CONSTASCII_USTRINGPARAM( "ValueSet item" ) ); - - return aRet; + return ::rtl::OUString(); } // ----------------------------------------------------------------------------- @@ -1239,7 +1236,7 @@ sal_Int32 SAL_CALL ValueItemAcc::getBackground( ) throw (uno::RuntimeException) { UINT32 nColor; - if (mpParent->meType == VALUESETITEM_COLOR) + if (mpParent && mpParent->meType == VALUESETITEM_COLOR) nColor = mpParent->maColor.GetColor(); else nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor(); diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx index f74cdf00a4db..abde4a015ab8 100644..100755 --- a/svtools/source/control/valueimp.hxx +++ b/svtools/source/control/valueimp.hxx @@ -111,6 +111,7 @@ struct ValueSet_Impl { ::std::auto_ptr< ValueItemList > mpItemList; bool mbIsTransientChildrenDisabled; + Link maHighlightHdl; ValueSet_Impl() : mpItemList( ::std::auto_ptr< ValueItemList >( new ValueItemList() ) ), mbIsTransientChildrenDisabled( false ) diff --git a/svtools/source/control/valueset.cxx b/svtools/source/control/valueset.cxx index bb48c11c7c0b..62193eadf735 100644 --- a/svtools/source/control/valueset.cxx +++ b/svtools/source/control/valueset.cxx @@ -1418,7 +1418,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) { USHORT nLastItem = (USHORT)mpImpl->mpItemList->Count(); USHORT nItemPos = VALUESET_ITEM_NOTFOUND; - USHORT nCurPos; + USHORT nCurPos = VALUESET_ITEM_NONEITEM; USHORT nCalcPos; if ( !nLastItem || !ImplGetFirstItem() ) @@ -1431,8 +1431,6 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) if ( mnSelItemId ) nCurPos = GetItemPos( mnSelItemId ); - else - nCurPos = VALUESET_ITEM_NONEITEM; nCalcPos = nCurPos; //switch off selection mode if key travelling is used @@ -1528,30 +1526,20 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) nCalcPos - ( nLineCount * mnCols )); else { - if( (KEY_UP == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) ) + if ( mpNoneItem ) { - Window* pParent = GetParent(); - pParent->GrabFocus(); - pParent->KeyInput( rKEvt ); - break; + mnCurCol = nCalcPos%mnCols; + nItemPos = VALUESET_ITEM_NONEITEM; } else { - if ( mpNoneItem ) - { - mnCurCol = nCalcPos%mnCols; - nItemPos = VALUESET_ITEM_NONEITEM; - } + if ( nLastItem+1 <= mnCols ) + nItemPos = nCalcPos; else { - if ( nLastItem+1 <= mnCols ) - nItemPos = nCalcPos; - else - { - nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols); - if ( nItemPos+mnCols <= nLastItem ) - nItemPos = nItemPos + mnCols; - } + nItemPos = ((((nLastItem+1)/mnCols)-1)*mnCols)+(nCalcPos%mnCols); + if ( nItemPos+mnCols <= nLastItem ) + nItemPos = nItemPos + mnCols; } } } @@ -1580,6 +1568,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) nCalcPos + ( nLineCount * mnCols )); else { +#if 0 if( (KEY_DOWN == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) ) { Window* pParent = GetParent(); @@ -1588,6 +1577,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) break; } else +#endif { if ( mpNoneItem ) { @@ -1620,7 +1610,6 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) bDefault = TRUE; break; } - if(!bDefault) EndSelection(); if ( nItemPos != VALUESET_ITEM_NOTFOUND ) @@ -1630,6 +1619,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt ) nItemId = GetItemId( nItemPos ); else nItemId = 0; + if ( nItemId != mnSelItemId ) { SelectItem( nItemId ); @@ -2278,6 +2268,7 @@ void ValueSet::SelectItem( USHORT nItemId ) ::com::sun::star::uno::Any aOldAny, aNewAny; ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny ); } + mpImpl->maHighlightHdl.Call(this); } } @@ -2749,3 +2740,19 @@ bool ValueSet::IsRTLActive (void) return Application::GetSettings().GetLayoutRTL() && IsRTLEnabled(); } +// ----------------------------------------------------------------------- + +void ValueSet::SetHighlightHdl( const Link& rLink ) +{ + mpImpl->maHighlightHdl = rLink; +} + +// ----------------------------------------------------------------------- + +const Link& ValueSet::GetHighlightHdl() const +{ + return mpImpl->maHighlightHdl; +} + +// ----------------------------------------------------------------------- + |