summaryrefslogtreecommitdiff
path: root/svtools/source
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source')
-rw-r--r--svtools/source/control/makefile.mk4
-rw-r--r--svtools/source/control/toolbarmenu.cxx1800
-rw-r--r--svtools/source/control/toolbarmenuacc.cxx956
-rw-r--r--svtools/source/control/toolbarmenuimp.hxx313
-rw-r--r--svtools/source/control/valueimp.hxx1
-rw-r--r--svtools/source/control/valueset.cxx28
-rw-r--r--svtools/source/uno/makefile.mk4
-rw-r--r--svtools/source/uno/popupmenucontrollerbase.cxx420
-rw-r--r--svtools/source/uno/popupwindowcontroller.cxx226
-rw-r--r--svtools/source/uno/toolboxcontroller.cxx109
10 files changed, 3846 insertions, 15 deletions
diff --git a/svtools/source/control/makefile.mk b/svtools/source/control/makefile.mk
index a40a81163eb3..a2e622730635 100644
--- 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..bb332c77cc49
--- /dev/null
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -0,0 +1,1800 @@
+/*************************************************************************
+ *
+ * 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 <comphelper/processfactory.hxx>
+
+#include <vcl/dockwin.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/image.hxx>
+#include <vcl/taskpanelist.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();
+}
+
+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;
+ }
+}
+
+// --------------------------------------------------------------------
+
+IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl )
+{
+ (void)pControl;
+ if( mpImpl->hasAccessibleListeners() )
+ mpImpl->fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
+ 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::GetFocus()
+{
+ if( mpImpl->mnHighlightedEntry == -1 )
+ implChangeHighlightEntry( 0 );
+
+ DockingWindow::GetFocus();
+
+ // Tell the accessible object that we got the focus.
+ if( mpImpl->mxAccessible.is() )
+ mpImpl->mxAccessible->GetFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::LoseFocus()
+{
+ if( mpImpl->mnHighlightedEntry != -1 )
+ implChangeHighlightEntry( -1 );
+
+ DockingWindow::LoseFocus();
+
+ // Tell the accessible object that we lost the focus.
+ if( mpImpl->mxAccessible.is() )
+ mpImpl->mxAccessible->LoseFocus();
+}
+
+// --------------------------------------------------------------------
+
+void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits )
+{
+ appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) );
+}
+
+
+#if 0
+todo acc selectentry?
+ if( ImplHasAccessibleListeners() )
+ {
+ // focus event (deselect)
+ if( nOldItem )
+ {
+ const USHORT nPos = GetItemPos( nItemId );
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ ValueItemAcc* pItemAcc = ValueItemAcc::getImplementation(
+ mpImpl->mpItemList->GetObject( nPos )->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
+
+ if( pItemAcc )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ if( !mpImpl->mbIsTransientChildrenDisabled)
+ {
+ aOldAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
+ static_cast< ::cppu::OWeakObject* >( pItemAcc ));
+ ImplFireAccessibleEvent (::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
+ }
+ else
+ {
+ aOldAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+ }
+ }
+ }
+ }
+
+ // focus event (select)
+ const USHORT nPos = GetItemPos( mnSelItemId );
+
+ ValueSetItem* pItem;
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pItem = mpImpl->mpItemList->GetObject(nPos);
+ else
+ pItem = mpNoneItem;
+
+ ValueItemAcc* pItemAcc = NULL;
+ if (pItem != NULL)
+ pItemAcc = ValueItemAcc::getImplementation(pItem->GetAccessible( mpImpl->mbIsTransientChildrenDisabled ) );
+
+ if( pItemAcc )
+ {
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ if( !mpImpl->mbIsTransientChildrenDisabled)
+ {
+ aNewAny <<= ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >(
+ static_cast< ::cppu::OWeakObject* >( pItemAcc ));
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOldAny, aNewAny );
+ }
+ else
+ {
+ aNewAny <<= ::com::sun::star::accessibility::AccessibleStateType::FOCUSED;
+ pItemAcc->FireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::STATE_CHANGED, aOldAny, aNewAny );
+ }
+ }
+
+ // selection event
+ ::com::sun::star::uno::Any aOldAny, aNewAny;
+ ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
+ }
+ }
+}
+
+#endif
+
+// --------------------------------------------------------------------
+
+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
+{
+ if( (nEntry < 0) || (nEntry >= (int)mpImpl->maEntryVector.size() ) )
+ return NULL;
+
+ return mpImpl->maEntryVector[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 )
+ 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 );
+ }
+
+ if( mpImpl->hasAccessibleListeners() )
+ mpImpl->fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, Any(), Any() );
+}
+
+// --------------------------------------------------------------------
+
+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;
+}
+
+// --------------------------------------------------------------------
+
+static void implHighlightControl( USHORT nCode, Control* pControl, int nLastColumn )
+{
+ 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) + nLastColumn, nItemCount-1 );
+ break;
+ }
+ case KEY_DOWN:
+ nItemPos = std::min( nLastColumn, nItemCount-1 );
+ break;
+ case KEY_END:
+ nItemPos = nItemCount -1;
+ break;
+ case KEY_HOME:
+ nItemPos = 0;
+ break;
+ }
+ pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) );
+ }
+}
+
+// --------------------------------------------------------------------
+
+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 )
+ {
+ implHighlightControl( nCode, p->mpControl, mpImpl->mnLastColumn );
+ }
+ 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 )
+ {
+ implHighlightControl( nCode, p->mpControl, mpImpl->mnLastColumn );
+ }
+ }
+ 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();
+
+ 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 )
+ {
+ // 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..702c1f72b83d
--- /dev/null
+++ b/svtools/source/control/toolbarmenuacc.cxx
@@ -0,0 +1,956 @@
+/*************************************************************************
+ *
+ * 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)
+{
+}
+
+// -----------------------------------------------------------------------------
+
+ToolbarMenuAcc::~ToolbarMenuAcc()
+{
+}
+
+// -----------------------------------------------------------------------
+
+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++;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void ToolbarMenuAcc::GetFocus (void)
+{
+ mbIsFocused = true;
+ FireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) );
+}
+
+// -----------------------------------------------------------------------------
+
+void ToolbarMenuAcc::LoseFocus (void)
+{
+ mbIsFocused = false;
+ FireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any( AccessibleStateType::FOCUSED ), Any() );
+}
+
+// -----------------------------------------------------------------------------
+
+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)
+ {
+ 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 OUString( RTL_CONSTASCII_USTRINGPARAM( "ToolbarMenu item" ) );
+}
+
+// -----------------------------------------------------------------------------
+
+::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..1d9037b61dc5
--- /dev/null
+++ b/svtools/source/control/toolbarmenuimp.hxx
@@ -0,0 +1,313 @@
+/*************************************************************************
+ *
+ * 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:
+
+ /** Called by the corresponding ToolbarMenu when it gets the focus.
+ Stores the new focus state and broadcasts a state change event.
+ */
+ void GetFocus (void);
+
+ /** Called by the corresponding ToolbarMenu when it loses the focus.
+ Stores the new focus state and broadcasts a state change event.
+ */
+ void LoseFocus (void);
+
+
+ // 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);
+
+private:
+ EventListenerVector mxEventListeners;
+ ToolbarMenu_Impl* mpParent;
+ /// The current FOCUSED state.
+ bool mbIsFocused;
+
+ /** 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;
+ 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);
+ 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();
+};
+
+}
diff --git a/svtools/source/control/valueimp.hxx b/svtools/source/control/valueimp.hxx
index f74cdf00a4db..abde4a015ab8 100644
--- 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..92c51bd6640e 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,6 +1526,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
nCalcPos - ( nLineCount * mnCols ));
else
{
+#if 0
if( (KEY_UP == rKEvt.GetKeyCode().GetCode() ) && (GetStyle() & WB_MENUSTYLEVALUESET) )
{
Window* pParent = GetParent();
@@ -1536,6 +1535,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
break;
}
else
+#endif
{
if ( mpNoneItem )
{
@@ -1580,6 +1580,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 +1589,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
break;
}
else
+#endif
{
if ( mpNoneItem )
{
@@ -1620,7 +1622,6 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
bDefault = TRUE;
break;
}
-
if(!bDefault)
EndSelection();
if ( nItemPos != VALUESET_ITEM_NOTFOUND )
@@ -1630,6 +1631,7 @@ void ValueSet::KeyInput( const KeyEvent& rKEvt )
nItemId = GetItemId( nItemPos );
else
nItemId = 0;
+
if ( nItemId != mnSelItemId )
{
SelectItem( nItemId );
@@ -2277,6 +2279,8 @@ void ValueSet::SelectItem( USHORT nItemId )
// selection event
::com::sun::star::uno::Any aOldAny, aNewAny;
ImplFireAccessibleEvent( ::com::sun::star::accessibility::AccessibleEventId::SELECTION_CHANGED, aOldAny, aNewAny );
+
+ mpImpl->maHighlightHdl.Call(this);
}
}
}
@@ -2749,3 +2753,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;
+}
+
+// -----------------------------------------------------------------------
+
diff --git a/svtools/source/uno/makefile.mk b/svtools/source/uno/makefile.mk
index 7bfe37624947..665301e9112d 100644
--- a/svtools/source/uno/makefile.mk
+++ b/svtools/source/uno/makefile.mk
@@ -55,7 +55,9 @@ SLOFILES= \
$(SLO)$/unoevent.obj \
$(SLO)$/unoiface.obj \
$(SLO)$/unoimap.obj \
- $(SLO)$/svtxgridcontrol.obj
+ $(SLO)$/svtxgridcontrol.obj \
+ $(SLO)$/popupwindowcontroller.obj \
+ $(SLO)$/popupmenucontrollerbase.obj
# --- Targets ------------------------------------------------------
diff --git a/svtools/source/uno/popupmenucontrollerbase.cxx b/svtools/source/uno/popupmenucontrollerbase.cxx
new file mode 100644
index 000000000000..ac75a1b9a24b
--- /dev/null
+++ b/svtools/source/uno/popupmenucontrollerbase.cxx
@@ -0,0 +1,420 @@
+/*************************************************************************
+ *
+ * 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"
+
+//_________________________________________________________________________________________________________________
+// my own includes
+//_________________________________________________________________________________________________________________
+#include "svtools/popupmenucontrollerbase.hxx"
+
+
+//_________________________________________________________________________________________________________________
+// interface includes
+//_________________________________________________________________________________________________________________
+#include <com/sun/star/awt/XDevice.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/awt/MenuItemStyle.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/awt/XMenuExtended.hpp>
+
+//_________________________________________________________________________________________________________________
+// includes of other projects
+//_________________________________________________________________________________________________________________
+
+#ifndef _VCL_MENU_HXX_
+#include <vcl/menu.hxx>
+#endif
+#include <vcl/svapp.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/logfile.hxx>
+#include <vos/mutex.hxx>
+
+//_________________________________________________________________________________________________________________
+// Defines
+//_________________________________________________________________________________________________________________
+//
+
+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::frame;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::util;
+
+namespace svt
+{
+
+struct PopupMenuControllerBaseDispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ PopupMenuControllerBaseDispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
+PopupMenuControllerBase::PopupMenuControllerBase( const Reference< XMultiServiceFactory >& xServiceManager ) :
+ ::comphelper::OBaseMutex(),
+ PopupMenuControllerBaseType(m_aMutex),
+ m_bInitialized( false ),
+ m_xServiceManager( xServiceManager )
+{
+ if ( m_xServiceManager.is() )
+ m_xURLTransformer.set( m_xServiceManager->createInstance(OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.util.URLTransformer"))),UNO_QUERY );
+}
+
+PopupMenuControllerBase::~PopupMenuControllerBase()
+{
+}
+
+// protected function
+void PopupMenuControllerBase::throwIfDisposed() throw ( RuntimeException )
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ throw com::sun::star::lang::DisposedException();
+}
+
+// protected function
+void PopupMenuControllerBase::resetPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu )
+{
+ VCLXPopupMenu* pPopupMenu = 0;
+ if ( rPopupMenu.is() && rPopupMenu->getItemCount() > 0 )
+ {
+ pPopupMenu = (VCLXPopupMenu *)VCLXMenu::GetImplementation( rPopupMenu );
+ if ( pPopupMenu )
+ {
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ PopupMenu* pVCLPopupMenu = (PopupMenu *)pPopupMenu->GetMenu();
+ pVCLPopupMenu->Clear();
+ }
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::disposing()
+{
+ // Reset our members and set disposed flag
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+ m_xServiceManager.clear();
+}
+
+// XServiceInfo
+
+sal_Bool SAL_CALL PopupMenuControllerBase::supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException)
+{
+ const Sequence< rtl::OUString > aSNL( getSupportedServiceNames() );
+ const rtl::OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XEventListener
+void SAL_CALL PopupMenuControllerBase::disposing( const EventObject& ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ m_xFrame.clear();
+ m_xDispatch.clear();
+ m_xPopupMenu.clear();
+}
+
+// XMenuListener
+void SAL_CALL PopupMenuControllerBase::highlight( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void PopupMenuControllerBase::impl_select(const Reference< XDispatch >& _xDispatch,const URL& aURL)
+{
+ Sequence<PropertyValue> aArgs;
+ OSL_ENSURE(_xDispatch.is(),"PopupMenuControllerBase::impl_select: No dispatch");
+ if ( _xDispatch.is() )
+ _xDispatch->dispatch( aURL, aArgs );
+}
+
+void SAL_CALL PopupMenuControllerBase::select( const awt::MenuEvent& rEvent ) throw (RuntimeException)
+{
+ throwIfDisposed();
+
+ osl::MutexGuard aLock( m_aMutex );
+
+ Reference< awt::XMenuExtended > xExtMenu( m_xPopupMenu, UNO_QUERY );
+ if( xExtMenu.is() )
+ {
+ Sequence<PropertyValue> aArgs;
+ dispatchCommand( xExtMenu->getCommand( rEvent.MenuId ), aArgs );
+ }
+}
+
+void PopupMenuControllerBase::dispatchCommand( const ::rtl::OUString& sCommandURL, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rArgs )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ throwIfDisposed();
+
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ m_xURLTransformer->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, PopupMenuControllerBase, ExecuteHdl_Impl), new PopupMenuControllerBaseDispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+
+}
+
+IMPL_STATIC_LINK_NOINSTANCE( PopupMenuControllerBase, ExecuteHdl_Impl, PopupMenuControllerBaseDispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void SAL_CALL PopupMenuControllerBase::activate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::deactivate( const awt::MenuEvent& ) throw (RuntimeException)
+{
+}
+
+void SAL_CALL PopupMenuControllerBase::updatePopupMenu() throw ( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ updateCommand( m_aCommandURL );
+}
+
+void SAL_CALL PopupMenuControllerBase::updateCommand( const rtl::OUString& rCommandURL )
+{
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ Reference< XStatusListener > xStatusListener( static_cast< OWeakObject* >( this ), UNO_QUERY );
+ Reference< XDispatch > xDispatch( m_xDispatch );
+ URL aTargetURL;
+ aTargetURL.Complete = rCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ aLock.clear();
+
+ // Add/remove status listener to get a status update once
+ if ( xDispatch.is() )
+ {
+ xDispatch->addStatusListener( xStatusListener, aTargetURL );
+ xDispatch->removeStatusListener( xStatusListener, aTargetURL );
+ }
+}
+
+
+// XDispatchProvider
+Reference< XDispatch > SAL_CALL
+PopupMenuControllerBase::queryDispatch(
+ const URL& /*aURL*/,
+ const rtl::OUString& /*sTarget*/,
+ sal_Int32 /*nFlags*/ )
+throw( RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ return Reference< XDispatch >();
+}
+
+Sequence< Reference< XDispatch > > SAL_CALL PopupMenuControllerBase::queryDispatches( const Sequence< DispatchDescriptor >& lDescriptor ) throw( RuntimeException )
+{
+ // Create return list - which must have same size then the given descriptor
+ // It's not allowed to pack it!
+ osl::ClearableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ sal_Int32 nCount = lDescriptor.getLength();
+ uno::Sequence< uno::Reference< frame::XDispatch > > lDispatcher( nCount );
+
+ // Step over all descriptors and try to get any dispatcher for it.
+ for( sal_Int32 i=0; i<nCount; ++i )
+ {
+ lDispatcher[i] = queryDispatch( lDescriptor[i].FeatureURL ,
+ lDescriptor[i].FrameName ,
+ lDescriptor[i].SearchFlags );
+ }
+
+ return lDispatcher;
+}
+
+// XDispatch
+void SAL_CALL
+PopupMenuControllerBase::dispatch(
+ const URL& /*aURL*/,
+ const Sequence< PropertyValue >& /*seqProperties*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ // must be implemented by subclass
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+}
+
+void SAL_CALL
+PopupMenuControllerBase::addStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& aURL )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ osl::ResettableMutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+ aLock.clear();
+
+ bool bStatusUpdate( false );
+ rBHelper.addListener( ::getCppuType( &xControl ), xControl );
+
+ aLock.reset();
+ if ( aURL.Complete.indexOf( m_aBaseURL ) == 0 )
+ bStatusUpdate = true;
+ aLock.clear();
+
+ if ( bStatusUpdate )
+ {
+ // Dummy update for popup menu controllers
+ FeatureStateEvent aEvent;
+ aEvent.FeatureURL = aURL;
+ aEvent.IsEnabled = sal_True;
+ aEvent.Requery = sal_False;
+ aEvent.State = Any();
+ xControl->statusChanged( aEvent );
+ }
+}
+
+void SAL_CALL PopupMenuControllerBase::removeStatusListener(
+ const Reference< XStatusListener >& xControl,
+ const URL& /*aURL*/ )
+throw( ::com::sun::star::uno::RuntimeException )
+{
+ rBHelper.removeListener( ::getCppuType( &xControl ), xControl );
+}
+
+::rtl::OUString PopupMenuControllerBase::determineBaseURL( const ::rtl::OUString& aURL )
+{
+ // Just use the main part of the URL for popup menu controllers
+ sal_Int32 nQueryPart( 0 );
+ sal_Int32 nSchemePart( 0 );
+ rtl::OUString aMainURL( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.popup:" ));
+
+ nSchemePart = aURL.indexOf( ':' );
+ if (( nSchemePart > 0 ) &&
+ ( aURL.getLength() > ( nSchemePart+1 )))
+ {
+ nQueryPart = aURL.indexOf( '?', nSchemePart );
+ if ( nQueryPart > 0 )
+ aMainURL += aURL.copy( nSchemePart, nQueryPart-nSchemePart );
+ else if ( nQueryPart == -1 )
+ aMainURL += aURL.copy( nSchemePart+1 );
+ }
+
+ return aMainURL;
+}
+
+// XInitialization
+void SAL_CALL PopupMenuControllerBase::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+
+ sal_Bool bInitalized( m_bInitialized );
+ if ( !bInitalized )
+ {
+ PropertyValue aPropValue;
+ rtl::OUString aCommandURL;
+ Reference< XFrame > xFrame;
+
+ for ( int i = 0; i < aArguments.getLength(); i++ )
+ {
+ if ( aArguments[i] >>= aPropValue )
+ {
+ if ( aPropValue.Name.equalsAscii( "Frame" ))
+ aPropValue.Value >>= xFrame;
+ else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ aPropValue.Value >>= aCommandURL;
+ }
+ }
+
+ if ( xFrame.is() && aCommandURL.getLength() )
+ {
+ m_xFrame = xFrame;
+ m_aCommandURL = aCommandURL;
+ m_aBaseURL = determineBaseURL( aCommandURL );
+ m_bInitialized = true;
+ }
+ }
+}
+// XPopupMenuController
+void SAL_CALL PopupMenuControllerBase::setPopupMenu( const Reference< awt::XPopupMenu >& xPopupMenu ) throw ( RuntimeException )
+{
+ osl::MutexGuard aLock( m_aMutex );
+ throwIfDisposed();
+
+ if ( m_xFrame.is() && !m_xPopupMenu.is() )
+ {
+ // Create popup menu on demand
+ vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() );
+
+ m_xPopupMenu = xPopupMenu;
+ m_xPopupMenu->addMenuListener( Reference< awt::XMenuListener >( (OWeakObject*)this, UNO_QUERY ));
+
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY );
+
+ URL aTargetURL;
+ aTargetURL.Complete = m_aCommandURL;
+ m_xURLTransformer->parseStrict( aTargetURL );
+ m_xDispatch = xDispatchProvider->queryDispatch( aTargetURL, ::rtl::OUString(), 0 );
+
+ impl_setPopupMenu();
+
+ updatePopupMenu();
+ }
+}
+void PopupMenuControllerBase::impl_setPopupMenu()
+{
+}
+}
diff --git a/svtools/source/uno/popupwindowcontroller.cxx b/svtools/source/uno/popupwindowcontroller.cxx
new file mode 100644
index 000000000000..d431dd7911a8
--- /dev/null
+++ b/svtools/source/uno/popupwindowcontroller.cxx
@@ -0,0 +1,226 @@
+/*************************************************************************
+ *
+ * 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 <toolkit/helper/vclunohelper.hxx>
+
+#include <vcl/toolbox.hxx>
+#include <vcl/svapp.hxx>
+
+#include "svtools/popupwindowcontroller.hxx"
+
+using rtl::OUString;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+
+
+namespace svt
+{
+
+class PopupWindowControllerImpl
+{
+public:
+ PopupWindowControllerImpl();
+ ~PopupWindowControllerImpl();
+
+ void SetPopupWindow( ::Window* pPopupWindow );
+
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+ DECL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window* );
+
+private:
+ ::Window* mpPopupWindow;
+};
+
+PopupWindowControllerImpl::PopupWindowControllerImpl()
+: mpPopupWindow( 0 )
+{
+}
+
+PopupWindowControllerImpl::~PopupWindowControllerImpl()
+{
+ if( mpPopupWindow )
+ SetPopupWindow(0);
+}
+
+void PopupWindowControllerImpl::SetPopupWindow( ::Window* pPopupWindow )
+{
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->RemoveEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ) );
+ Application::PostUserEvent( STATIC_LINK( this, PopupWindowControllerImpl, AsyncDeleteWindowHdl ), mpPopupWindow );
+ }
+ mpPopupWindow = pPopupWindow;
+ if( mpPopupWindow )
+ {
+ mpPopupWindow->AddEventListener( LINK( this, PopupWindowControllerImpl, WindowEventListener ));
+ }
+}
+
+IMPL_LINK( PopupWindowControllerImpl, WindowEventListener, VclSimpleEvent*, pEvent )
+{
+ VclWindowEvent* pWindowEvent = dynamic_cast< VclWindowEvent* >( pEvent );
+ if( pWindowEvent )
+ {
+ switch( pWindowEvent->GetId() )
+ {
+ case VCLEVENT_WINDOW_CLOSE:
+ case VCLEVENT_WINDOW_ENDPOPUPMODE:
+ SetPopupWindow(0);
+ break;
+ }
+ }
+ return 1;
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK( PopupWindowControllerImpl, AsyncDeleteWindowHdl, Window*, pWindow )
+{
+ (void)*pThis;
+ delete pWindow;
+ return 0;
+}
+
+//========================================================================
+// class PopupWindowController
+//========================================================================
+
+PopupWindowController::PopupWindowController( const Reference< lang::XMultiServiceFactory >& rServiceManager,
+ const Reference< frame::XFrame >& xFrame,
+ const OUString& aCommandURL )
+: svt::ToolboxController( rServiceManager, xFrame, aCommandURL )
+, mpImpl( new PopupWindowControllerImpl() )
+{
+}
+
+PopupWindowController::~PopupWindowController()
+{
+}
+
+// XInterface
+Any SAL_CALL PopupWindowController::queryInterface( const Type& aType )
+throw (RuntimeException)
+{
+ Any a( ToolboxController::queryInterface( aType ) );
+ if ( a.hasValue() )
+ return a;
+
+ return ::cppu::queryInterface( aType, static_cast< lang::XServiceInfo* >( this ));
+}
+
+void SAL_CALL PopupWindowController::acquire() throw ()
+{
+ ToolboxController::acquire();
+}
+
+void SAL_CALL PopupWindowController::release() throw ()
+{
+ ToolboxController::release();
+}
+
+// XServiceInfo
+sal_Bool SAL_CALL PopupWindowController::supportsService( const OUString& ServiceName ) throw(RuntimeException)
+{
+ const Sequence< OUString > aSNL( getSupportedServiceNames() );
+ const OUString * pArray = aSNL.getConstArray();
+
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return true;
+
+ return false;
+}
+
+// XInitialization
+void SAL_CALL PopupWindowController::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ svt::ToolboxController::initialize( aArguments );
+ if( m_aCommandURL.getLength() )
+ addStatusListener( m_aCommandURL );
+}
+
+// XComponent
+void SAL_CALL PopupWindowController::dispose() throw (RuntimeException)
+{
+ if( m_aCommandURL.getLength() )
+ removeStatusListener( m_aCommandURL );
+
+ svt::ToolboxController::dispose();
+}
+
+
+// XStatusListener
+void SAL_CALL PopupWindowController::statusChanged( const frame::FeatureStateEvent& rEvent ) throw ( RuntimeException )
+{
+ svt::ToolboxController::statusChanged(rEvent);
+ enable( rEvent.IsEnabled );
+}
+
+// XToolbarController
+void SAL_CALL PopupWindowController::execute( sal_Int16 KeyModifier ) throw (RuntimeException)
+{
+ svt::ToolboxController::execute( KeyModifier );
+}
+
+void SAL_CALL PopupWindowController::click() throw (RuntimeException)
+{
+ svt::ToolboxController::click();
+}
+
+void SAL_CALL PopupWindowController::doubleClick() throw (RuntimeException)
+{
+ svt::ToolboxController::doubleClick();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createPopupWindow() throw (RuntimeException)
+{
+ ToolBox* pToolBox = dynamic_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+ if( pToolBox )
+ {
+ ::Window* pWin = createPopupWindow(pToolBox);
+ if( pWin )
+ {
+ pWin->EnableDocking(true);
+ mpImpl->SetPopupWindow(pWin);
+ ::Window::GetDockingManager()->StartPopupMode( pToolBox, pWin, FLOATWIN_POPUPMODE_NOFOCUSCLOSE|FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE );
+ }
+ }
+ return Reference< awt::XWindow >();
+}
+
+Reference< awt::XWindow > SAL_CALL PopupWindowController::createItemWindow( const Reference< awt::XWindow >& /*Parent*/ )
+ throw (RuntimeException)
+{
+ return Reference< awt::XWindow >();
+}
+
+}
+
diff --git a/svtools/source/uno/toolboxcontroller.cxx b/svtools/source/uno/toolboxcontroller.cxx
index 3f0b4e7c0ee6..d9b84aa2e356 100644
--- a/svtools/source/uno/toolboxcontroller.cxx
+++ b/svtools/source/uno/toolboxcontroller.cxx
@@ -43,6 +43,8 @@
#endif
#include <vcl/toolbox.hxx>
+using ::rtl::OUString;
+
using namespace ::cppu;
using namespace ::com::sun::star::awt;
using namespace ::com::sun::star::uno;
@@ -54,10 +56,29 @@ using namespace ::com::sun::star::frame;
namespace svt
{
+
+struct DispatchInfo
+{
+ Reference< XDispatch > mxDispatch;
+ const URL maURL;
+ const Sequence< PropertyValue > maArgs;
+
+ DispatchInfo( const Reference< XDispatch >& xDispatch, const URL& rURL, const Sequence< PropertyValue >& rArgs )
+ : mxDispatch( xDispatch ), maURL( rURL ), maArgs( rArgs ) {}
+};
+
struct ToolboxController_Impl
{
::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > m_xParentWindow;
::com::sun::star::uno::Reference< ::com::sun::star::util::XURLTransformer > m_xUrlTransformer;
+ rtl::OUString m_sModuleName;
+ sal_uInt16 m_nToolBoxId;
+
+ DECL_STATIC_LINK( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo* );
+
+ ToolboxController_Impl()
+ : m_nToolBoxId( SAL_MAX_UINT16 )
+ {}
};
ToolboxController::ToolboxController(
@@ -166,11 +187,6 @@ void SAL_CALL ToolboxController::release() throw ()
void SAL_CALL ToolboxController::initialize( const Sequence< Any >& aArguments )
throw ( Exception, RuntimeException )
{
- const rtl::OUString aFrameName( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
- const rtl::OUString aCommandURLName( RTL_CONSTASCII_USTRINGPARAM( "CommandURL" ));
- const rtl::OUString aServiceManagerName( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager" ));
- const rtl::OUString aParentWindow( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ));
-
bool bInitialized( true );
{
@@ -192,14 +208,16 @@ throw ( Exception, RuntimeException )
{
if ( aArguments[i] >>= aPropValue )
{
- if ( aPropValue.Name.equalsAscii( "Frame" ))
+ if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Frame") ))
m_xFrame.set(aPropValue.Value,UNO_QUERY);
- else if ( aPropValue.Name.equalsAscii( "CommandURL" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("CommandURL") ))
aPropValue.Value >>= m_aCommandURL;
- else if ( aPropValue.Name.equalsAscii( "ServiceManager" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ServiceManager") ))
m_xServiceManager.set(aPropValue.Value,UNO_QUERY);
- else if ( aPropValue.Name.equalsAscii( "ParentWindow" ))
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ParentWindow") ))
m_pImpl->m_xParentWindow.set(aPropValue.Value,UNO_QUERY);
+ else if ( aPropValue.Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("ModuleName" ) ) )
+ aPropValue.Value >>= m_pImpl->m_sModuleName;
}
}
@@ -704,4 +722,77 @@ Reference< ::com::sun::star::awt::XWindow > ToolboxController::getParent() const
{
return m_pImpl->m_xParentWindow;
}
+
+const rtl::OUString& ToolboxController::getModuleName() const
+{
+ return m_pImpl->m_sModuleName;
+}
+
+void ToolboxController::dispatchCommand( const OUString& sCommandURL, const Sequence< PropertyValue >& rArgs )
+{
+ try
+ {
+ Reference< XDispatchProvider > xDispatchProvider( m_xFrame, UNO_QUERY_THROW );
+ URL aURL;
+ aURL.Complete = sCommandURL;
+ getURLTransformer()->parseStrict( aURL );
+
+ Reference< XDispatch > xDispatch( xDispatchProvider->queryDispatch( aURL, OUString(), 0 ), UNO_QUERY_THROW );
+
+ Application::PostUserEvent( STATIC_LINK(0, ToolboxController_Impl, ExecuteHdl_Impl), new DispatchInfo( xDispatch, aURL, rArgs ) );
+
+ }
+ catch( Exception& )
+ {
+ }
+}
+
+//--------------------------------------------------------------------
+
+IMPL_STATIC_LINK_NOINSTANCE( ToolboxController_Impl, ExecuteHdl_Impl, DispatchInfo*, pDispatchInfo )
+{
+ pDispatchInfo->mxDispatch->dispatch( pDispatchInfo->maURL, pDispatchInfo->maArgs );
+ delete pDispatchInfo;
+ return 0;
+}
+
+void ToolboxController::enable( bool bEnable )
+{
+ ToolBox* pToolBox = 0;
+ sal_uInt16 nItemId = 0;
+ if( getToolboxId( nItemId, &pToolBox ) )
+ {
+ pToolBox->EnableItem( nItemId, bEnable ? TRUE : FALSE );
+ }
+}
+
+bool ToolboxController::getToolboxId( sal_uInt16& rItemId, ToolBox** ppToolBox )
+{
+ if( (m_pImpl->m_nToolBoxId != SAL_MAX_UINT16) && (ppToolBox == 0) )
+ return m_pImpl->m_nToolBoxId;
+
+ ToolBox* pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
+
+ if( (m_pImpl->m_nToolBoxId == SAL_MAX_UINT16) && pToolBox )
+ {
+ const sal_uInt16 nCount = pToolBox->GetItemCount();
+ for ( sal_uInt16 nPos = 0; nPos < nCount; ++nPos )
+ {
+ const sal_uInt16 nItemId = pToolBox->GetItemId( nPos );
+ if ( pToolBox->GetItemCommand( nItemId ) == String( m_aCommandURL ) )
+ {
+ m_pImpl->m_nToolBoxId = nItemId;
+ break;
+ }
+ }
+ }
+
+ if( ppToolBox )
+ *ppToolBox = pToolBox;
+
+ rItemId = m_pImpl->m_nToolBoxId;
+
+ return (rItemId != SAL_MAX_UINT16) && (( ppToolBox == 0) || (*ppToolBox != 0) );
+}
+
} // svt