blob: a83ada36941e8eeb95fe735251e9215c7d4f79b3 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_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( sal_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 );
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
SetControlBackground( rStyleSettings.GetMenuColor() );
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();
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( sal_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,
aCtrlRect,
CTRL_STATE_ENABLED,
ImplControlValue(),
OUString() );
if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
{
bDrawItemRect = false;
if( sal_False == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
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 = sal_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 )
{
sal_uInt16 nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() );
if( nItemPos != VALUESET_ITEM_NOTFOUND )
{
const sal_uInt16 nColCount = pValueSet->GetColCount();
const sal_uInt16 nLine = nItemPos / nColCount;
nLastColumn = nItemPos - (nLine * nColCount);
if( bUp )
{
return nLine > 0;
}
else
{
const sal_uInt16 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( sal_uInt16 nCode, Control* pControl )
{
ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
if( pValueSet )
{
const sal_uInt16 nItemCount = pValueSet->GetItemCount();
sal_uInt16 nItemPos = VALUESET_ITEM_NOTFOUND;
switch( nCode )
{
case KEY_UP:
{
const sal_uInt16 nColCount = pValueSet->GetColCount();
const sal_uInt16 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;
sal_uInt16 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 )
{
sal_Bool bNativeOk = sal_False;
if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
{
ImplControlValue aControlValue;
ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED;
aControlValue.setTristateVal( BUTTONVALUE_ON );
bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
i_rRect, 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, sal_True, sal_False, 2, NULL, &aColor );
}
}
static long ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth )
{
rMaxWidth = rCheckHeight = rRadioHeight = 0;
ImplControlValue aVal;
Rectangle aNativeBounds;
Rectangle aNativeContent;
Point tmp( 0, 0 );
Rectangle aCtrlRegion( 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.GetHeight();
rMaxWidth = aNativeContent.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.GetHeight();
rMaxWidth = Max (rMaxWidth, aNativeContent.GetWidth());
}
}
return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight;
}
void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted )
{
sal_uInt16 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);
sal_uInt16 nTextStyle = 0;
sal_uInt16 nSymbolStyle = 0;
sal_uInt16 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, 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;
sal_uInt16 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;
}
// --------------------------------------------------------------------
// --------------------------------------------------------------------
}