update emoji autocorrect entries from po-files
[LibreOffice.git] / svtools / source / control / toolbarmenu.cxx
blob115ea353c48e7c344e0e55ac92c39ae72cecd286
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
21 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
22 #include <comphelper/processfactory.hxx>
24 #include <vcl/dockwin.hxx>
25 #include <vcl/decoview.hxx>
26 #include <vcl/image.hxx>
27 #include <vcl/taskpanelist.hxx>
28 #include <vcl/toolbox.hxx>
29 #include <vcl/settings.hxx>
31 #include <svtools/valueset.hxx>
32 #include <svtools/toolbarmenu.hxx>
33 #include "toolbarmenuimp.hxx"
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::lang;
37 using namespace ::com::sun::star::frame;
38 using namespace ::com::sun::star::accessibility;
40 namespace svtools {
42 static vcl::Window* GetTopMostParentSystemWindow( vcl::Window* pWindow )
44 OSL_ASSERT( pWindow );
45 if ( pWindow )
47 // ->manually search topmost system window
48 // required because their might be another system window between this and the top window
49 pWindow = pWindow->GetParent();
50 SystemWindow* pTopMostSysWin = NULL;
51 while ( pWindow )
53 if ( pWindow->IsSystemWindow() )
54 pTopMostSysWin = static_cast<SystemWindow*>(pWindow);
55 pWindow = pWindow->GetParent();
57 pWindow = pTopMostSysWin;
58 OSL_ASSERT( pWindow );
59 return pWindow;
62 return NULL;
67 void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits )
69 mnEntryId = nEntryId;
70 mnBits = nBits;
72 mbHasText = false;
73 mbHasImage = false;
74 mbChecked = false;
75 mbEnabled = true;
77 mpControl = NULL;
82 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const OUString& rText, MenuItemBits nBits )
83 : mrMenu( rMenu )
85 init( nEntryId, nBits );
87 maText = rText;
88 mbHasText = true;
93 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const OUString& rText, MenuItemBits nBits )
94 : mrMenu( rMenu )
96 init( nEntryId, nBits );
98 maText = rText;
99 mbHasText = true;
101 maImage = rImage;
102 mbHasImage = true;
107 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits )
108 : mrMenu( rMenu )
110 init( nEntryId, nBits );
112 if( pControl )
114 mpControl = pControl;
115 mpControl->Show();
121 ToolbarMenuEntry::~ToolbarMenuEntry()
123 if( mxAccContext.is() )
125 Reference< XComponent > xComponent( mxAccContext, UNO_QUERY );
126 if( xComponent.is() )
127 xComponent->dispose();
128 mxAccContext.clear();
130 mpControl.disposeAndClear();
135 const Reference< XAccessibleContext >& ToolbarMenuEntry::GetAccessible( bool bCreate /* = false */ )
137 if( !mxAccContext.is() && bCreate )
139 if( mpControl )
141 mxAccContext = Reference< XAccessibleContext >( mpControl->GetAccessible( true ), UNO_QUERY );
143 else
145 mxAccContext = Reference< XAccessibleContext >( new ToolbarMenuEntryAcc( this ) );
149 return mxAccContext;
154 sal_Int32 ToolbarMenuEntry::getAccessibleChildCount() throw (RuntimeException)
156 if( mpControl )
158 const Reference< XAccessibleContext >& xContext = GetAccessible( true );
159 if( xContext.is() )
161 return xContext->getAccessibleChildCount();
164 return 1;
169 Reference< XAccessible > ToolbarMenuEntry::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
171 const Reference< XAccessibleContext >& xContext = GetAccessible( true );
172 if( mpControl )
174 if( xContext.is() )
176 return xContext->getAccessibleChild(index);
179 else if( index == 0 )
181 Reference< XAccessible > xRet( xContext, UNO_QUERY );
182 if( xRet.is() )
183 return xRet;
186 throw IndexOutOfBoundsException();
191 ToolbarMenu_Impl::ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame )
192 : mrMenu( rMenu )
193 , mxFrame( xFrame )
194 , mnCheckPos(0)
195 , mnImagePos(0)
196 , mnTextPos(0)
197 , mnHighlightedEntry(-1)
198 , mnSelectedEntry(-1)
199 , mnLastColumn(0)
205 ToolbarMenu_Impl::~ToolbarMenu_Impl()
207 setAccessible( 0 );
212 void ToolbarMenu_Impl::setAccessible( ToolbarMenuAcc* pAccessible )
214 if( mxAccessible.get() != pAccessible )
216 if( mxAccessible.is() )
217 mxAccessible->dispose();
219 mxAccessible.set( pAccessible );
225 void ToolbarMenu_Impl::fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
227 if( mxAccessible.is() )
228 mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
233 bool ToolbarMenu_Impl::hasAccessibleListeners()
235 return( mxAccessible.is() && mxAccessible->HasAccessibleListeners() );
240 sal_Int32 ToolbarMenu_Impl::getAccessibleChildCount() throw (RuntimeException)
242 sal_Int32 nCount = 0;
243 const int nEntryCount = maEntryVector.size();
244 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
246 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
247 if( pEntry )
249 if( pEntry->mpControl )
251 nCount += pEntry->getAccessibleChildCount();
253 else
255 nCount += 1;
260 return nCount;
265 Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
267 const int nEntryCount = maEntryVector.size();
268 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
270 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
271 if( pEntry )
273 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
274 if( index < nCount )
276 return pEntry->getAccessibleChild( index );
278 index -= nCount;
282 throw IndexOutOfBoundsException();
287 Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (IndexOutOfBoundsException, RuntimeException)
289 const int nEntryCount = maEntryVector.size();
290 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
292 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
293 if( pEntry && (pEntry->mpControl.get() == pControl) )
295 return pEntry->getAccessibleChild( childIndex );
299 throw IndexOutOfBoundsException();
304 void ToolbarMenu_Impl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
306 const int nEntryCount = maEntryVector.size();
307 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
309 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
310 if( pEntry )
312 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
313 if( nChildIndex < nCount )
315 if( pEntry->mpControl )
317 Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
318 xSel->selectAccessibleChild(nChildIndex);
320 else if( pEntry->mnEntryId != TITLE_ID )
322 mrMenu.implSelectEntry( nEntry );
324 return;
326 nChildIndex -= nCount;
330 throw IndexOutOfBoundsException();
335 bool ToolbarMenu_Impl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
337 const int nEntryCount = maEntryVector.size();
338 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
340 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
341 if( pEntry )
343 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
344 if( nChildIndex < nCount )
346 if( mnHighlightedEntry == nEntry )
348 if( pEntry->mpControl )
350 Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
351 xSel->isAccessibleChildSelected(nChildIndex);
353 return true;
355 else
357 return false;
360 nChildIndex -= nCount;
364 throw IndexOutOfBoundsException();
369 void ToolbarMenu_Impl::clearAccessibleSelection()
371 if( mnHighlightedEntry != -1 )
373 mrMenu.Invalidate();
374 mnHighlightedEntry = -1;
381 void ToolbarMenu_Impl::notifyHighlightedEntry()
383 if( hasAccessibleListeners() )
385 ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
386 if( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
388 Any aNew;
389 Any aOld( mxOldSelection );
390 if( pEntry->mpControl )
392 sal_Int32 nChildIndex = 0;
393 // todo: if other controls than ValueSet are allowed, addapt this code
394 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl.get() );
395 if( pValueSet )
396 nChildIndex = static_cast< sal_Int32 >( pValueSet->GetItemPos( pValueSet->GetSelectItemId() ) );
398 if( (nChildIndex >= pEntry->getAccessibleChildCount()) || (nChildIndex < 0) )
399 return;
401 aNew <<= getAccessibleChild( pEntry->mpControl, nChildIndex );
403 else
405 aNew <<= pEntry->GetAccessible(true);
408 fireAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOld, aNew );
409 fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOld, aNew );
410 fireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) );
411 aNew >>= mxOldSelection;
418 ToolbarMenuEntry* ToolbarMenu_Impl::implGetEntry( int nEntry ) const
420 if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) )
421 return NULL;
423 return maEntryVector[nEntry];
429 IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl )
431 (void)pControl;
432 mpImpl->notifyHighlightedEntry();
433 return 0;
436 ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, vcl::Window* pParentWindow, WinBits nBits )
437 : DockingWindow(pParentWindow, nBits)
439 implInit(rFrame);
442 void ToolbarMenu::implInit(const Reference< XFrame >& rFrame)
444 mpImpl = new ToolbarMenu_Impl( *this, rFrame );
446 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
447 SetControlBackground( rStyleSettings.GetMenuColor() );
449 initWindow();
451 vcl::Window* pWindow = GetTopMostParentSystemWindow( this );
452 if ( pWindow )
453 static_cast<SystemWindow*>(pWindow)->GetTaskPaneList()->AddWindow( this );
458 ToolbarMenu::~ToolbarMenu()
460 disposeOnce();
463 void ToolbarMenu::dispose()
465 vcl::Window* pWindow = GetTopMostParentSystemWindow( this );
466 if ( pWindow )
467 static_cast<SystemWindow*>(pWindow)->GetTaskPaneList()->RemoveWindow( this );
469 if ( mpImpl->mxStatusListener.is() )
471 mpImpl->mxStatusListener->dispose();
472 mpImpl->mxStatusListener.clear();
475 // delete all menu entries
476 const int nEntryCount = mpImpl->maEntryVector.size();
477 int nEntry;
478 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
480 delete mpImpl->maEntryVector[nEntry];
483 delete mpImpl;
484 mpImpl = NULL;
486 DockingWindow::dispose();
491 int ToolbarMenu::getSelectedEntryId() const
493 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnSelectedEntry );
494 return pEntry ? pEntry->mnEntryId : -1;
499 int ToolbarMenu::getHighlightedEntryId() const
501 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
502 return pEntry ? pEntry->mnEntryId : -1;
507 void ToolbarMenu::checkEntry( int nEntryId, bool bChecked )
509 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
510 if( pEntry && pEntry->mbChecked != bChecked )
512 pEntry->mbChecked = bChecked;
513 Invalidate();
519 void ToolbarMenu::enableEntry( int nEntryId, bool bEnable )
521 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
522 if( pEntry && pEntry->mbEnabled != bEnable )
524 pEntry->mbEnabled = bEnable;
525 if( pEntry->mpControl )
527 pEntry->mpControl->Enable( bEnable );
529 // hack for the valueset to make it paint itself anew
530 pEntry->mpControl->Resize();
532 Invalidate();
538 void ToolbarMenu::setEntryText( int nEntryId, const OUString& rStr )
540 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
541 if( pEntry && pEntry->maText != rStr )
543 pEntry->maText = rStr;
544 mpImpl->maSize = implCalcSize();
545 if( IsVisible() )
546 Invalidate();
552 void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage )
554 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
555 if( pEntry && pEntry->maImage != rImage )
557 pEntry->maImage = rImage;
558 mpImpl->maSize = implCalcSize();
559 if( IsVisible() )
560 Invalidate();
566 void ToolbarMenu::initWindow()
568 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
570 // FIXME RenderContext
571 SetPointFont(*this, rStyleSettings.GetMenuFont());
572 SetBackground(Wallpaper(GetControlBackground()));
573 SetTextColor(rStyleSettings.GetMenuTextColor());
574 SetTextFillColor();
575 SetLineColor();
577 mpImpl->maSize = implCalcSize();
582 static long ImplGetNativeCheckAndRadioSize(vcl::RenderContext& rRenderContext, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth )
584 rMaxWidth = rCheckHeight = rRadioHeight = 0;
586 ImplControlValue aVal;
587 Rectangle aNativeBounds;
588 Rectangle aNativeContent;
589 Point tmp( 0, 0 );
590 Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
591 if (rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK))
593 if (rRenderContext.GetNativeControlRegion(ControlType(CTRL_MENU_POPUP), ControlPart(PART_MENU_ITEM_CHECK_MARK),
594 aCtrlRegion, ControlState(ControlState::ENABLED), aVal, OUString(),
595 aNativeBounds, aNativeContent)
598 rCheckHeight = aNativeBounds.GetHeight();
599 rMaxWidth = aNativeContent.GetWidth();
602 if (rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK))
604 if (rRenderContext.GetNativeControlRegion(ControlType(CTRL_MENU_POPUP), ControlPart(PART_MENU_ITEM_RADIO_MARK),
605 aCtrlRegion, ControlState(ControlState::ENABLED), aVal, OUString(),
606 aNativeBounds, aNativeContent)
609 rRadioHeight = aNativeBounds.GetHeight();
610 rMaxWidth = std::max (rMaxWidth, aNativeContent.GetWidth());
613 return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight;
616 #define gfxExtra 7
618 Size ToolbarMenu::implCalcSize()
620 const long nFontHeight = GetTextHeight();
621 long nExtra = nFontHeight/4;
623 Size aSz;
624 Size aMaxImgSz;
625 long nMaxTextWidth = 0;
626 long nMinMenuItemHeight = nFontHeight+2;
628 const int nEntryCount = mpImpl->maEntryVector.size();
629 int nEntry;
631 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
632 const bool bUseImages = rSettings.GetUseImagesInMenus();
634 // get maximum image size
635 if( bUseImages )
637 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
639 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
640 if( pEntry && pEntry->mbHasImage )
642 Size aImgSz( pEntry->maImage.GetSizePixel() );
643 nMinMenuItemHeight = std::max( nMinMenuItemHeight, aImgSz.Height() + 6 );
644 aMaxImgSz.Width() = std::max( aMaxImgSz.Width(), aImgSz.Width() );
649 mpImpl->mnCheckPos = nExtra;
650 mpImpl->mnImagePos = nExtra;
651 mpImpl->mnTextPos = mpImpl->mnImagePos + aMaxImgSz.Width();
653 if ( aMaxImgSz.Width() )
654 mpImpl->mnTextPos += std::max( nExtra, 7L );
656 // set heights, calc maximum width
657 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
659 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
661 if( pEntry )
663 // Text:
664 if( pEntry->mbHasText || pEntry->mbHasImage )
666 pEntry->maSize.Height() = nMinMenuItemHeight;
668 if( pEntry->mbHasText )
670 long nTextWidth = GetCtrlTextWidth( pEntry->maText ) + mpImpl->mnTextPos + nExtra;
671 nMaxTextWidth = std::max( nTextWidth, nMaxTextWidth );
674 // Control:
675 else if( pEntry->mpControl )
677 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
679 nMaxTextWidth = std::max( aControlSize.Width(), nMaxTextWidth );
680 pEntry->maSize.Height() = aControlSize.Height() + 1;
683 if( pEntry->HasCheck() && !pEntry->mbHasImage )
685 if (IsNativeControlSupported(CTRL_MENU_POPUP, (pEntry->mnBits & MenuItemBits::RADIOCHECK)
686 ? PART_MENU_ITEM_CHECK_MARK
687 : PART_MENU_ITEM_RADIO_MARK ) )
689 long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
690 ImplGetNativeCheckAndRadioSize(*this, nCheckHeight, nRadioHeight, nMaxCheckWidth);
692 long nCtrlHeight = (pEntry->mnBits & MenuItemBits::RADIOCHECK) ? nCheckHeight : nRadioHeight;
693 nMaxTextWidth += nCtrlHeight + gfxExtra;
695 else if( pEntry->mbChecked )
697 long nSymbolWidth = (nFontHeight*25)/40;
698 if ( pEntry->mnBits & MenuItemBits::RADIOCHECK )
699 nSymbolWidth = nFontHeight/2;
701 nMaxTextWidth += nSymbolWidth;
707 aSz.Width() = nMaxTextWidth + (BORDER_X<<1);
709 // positionate controls
710 int nY = BORDER_Y;
711 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
713 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
715 if (pEntry)
717 pEntry->maSize.Width() = nMaxTextWidth;
719 if( pEntry->mpControl )
721 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
722 Point aControlPos( (aSz.Width() - aControlSize.Width())>>1, nY);
724 pEntry->mpControl->SetPosPixel( aControlPos );
726 pEntry->maRect = Rectangle( aControlPos, aControlSize );
728 else
730 pEntry->maRect = Rectangle( Point( 0, nY ), pEntry->maSize );
733 nY += pEntry->maSize.Height();
735 else
737 nY += SEPARATOR_HEIGHT;
741 aSz.Height() += nY + BORDER_Y;
743 return aSz;
748 void ToolbarMenu::highlightFirstEntry()
750 implChangeHighlightEntry( 0 );
755 void ToolbarMenu::GetFocus()
757 if( mpImpl->mnHighlightedEntry == -1 )
758 implChangeHighlightEntry( 0 );
760 DockingWindow::GetFocus();
765 void ToolbarMenu::LoseFocus()
767 if( mpImpl && mpImpl->mnHighlightedEntry != -1 )
768 implChangeHighlightEntry( -1 );
770 DockingWindow::LoseFocus();
775 void ToolbarMenu::appendEntry( int nEntryId, const OUString& rStr, MenuItemBits nItemBits )
777 appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) );
782 void ToolbarMenu::appendEntry( int nEntryId, const OUString& rStr, const Image& rImage, MenuItemBits nItemBits )
784 appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, rStr, nItemBits ) );
789 void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits )
791 appendEntry( new ToolbarMenuEntry( *this, nEntryId, pControl, nItemBits ) );
796 void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry )
798 mpImpl->maEntryVector.push_back(pEntry);
799 mpImpl->maSize = implCalcSize();
800 if (IsVisible())
801 Invalidate();
806 void ToolbarMenu::appendSeparator()
808 appendEntry( 0 );
813 /** creates an empty ValueSet that is initialized and can be inserted with appendEntry. */
814 VclPtr<ValueSet> ToolbarMenu::createEmptyValueSetControl()
816 VclPtr<ValueSet> pSet = VclPtr<ValueSet>::Create( this, WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT );
817 pSet->EnableFullItemMode( false );
818 pSet->SetColor( GetControlBackground() );
819 pSet->SetHighlightHdl( LINK( this, ToolbarMenu, HighlightHdl ) );
820 return pSet;
825 ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const
827 return mpImpl->implGetEntry( nEntry );
832 ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const
834 const int nEntryCount = mpImpl->maEntryVector.size();
835 int nEntry;
836 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
838 ToolbarMenuEntry* p = mpImpl->maEntryVector[nEntry];
839 if( p && p->mnEntryId == nEntryId )
841 return p;
845 return NULL;
850 void ToolbarMenu::implHighlightEntry(vcl::RenderContext& rRenderContext, int nHighlightEntry, bool bHighlight)
852 Size aSz(GetOutputSizePixel());
853 long nX = 0;
854 long nY = 0;
856 const int nEntryCount = mpImpl->maEntryVector.size();
858 for (int nEntry = 0; nEntry < nEntryCount; nEntry++)
860 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
861 if (pEntry && (nEntry == nHighlightEntry))
863 // no highlights for controls only items
864 if (pEntry->mpControl)
866 if (!bHighlight)
868 ValueSet* pValueSet = dynamic_cast<ValueSet*>(pEntry->mpControl.get());
869 if (pValueSet)
871 pValueSet->SetNoSelection();
874 break;
877 bool bRestoreLineColor = false;
878 Color oldLineColor;
879 bool bDrawItemRect = true;
881 Rectangle aItemRect(Point(nX, nY), Size(aSz.Width(), pEntry->maSize.Height()));
882 if (pEntry->mnBits & MenuItemBits::POPUPSELECT)
884 long nFontHeight = GetTextHeight();
885 aItemRect.Right() -= nFontHeight + nFontHeight / 4;
888 if (rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
890 Size aPxSize(GetOutputSizePixel());
891 rRenderContext.Push(PushFlags::CLIPREGION);
892 rRenderContext.IntersectClipRegion(Rectangle(Point(nX, nY), Size(aSz.Width(), pEntry->maSize.Height())));
893 Rectangle aCtrlRect(Point(nX, 0), Size(aPxSize.Width() - nX, aPxSize.Height()));
894 rRenderContext.DrawNativeControl(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect,
895 ControlState::ENABLED, ImplControlValue(), OUString());
896 if (bHighlight && rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
898 bDrawItemRect = false;
899 ControlState eState = ControlState::SELECTED | (pEntry->mbEnabled ? ControlState::ENABLED : ControlState::NONE);
900 if (!rRenderContext.DrawNativeControl(CTRL_MENU_POPUP, PART_MENU_ITEM, aItemRect,
901 eState, ImplControlValue(), OUString()))
903 bDrawItemRect = bHighlight;
906 else
908 bDrawItemRect = bHighlight;
910 rRenderContext.Pop();
912 if (bDrawItemRect)
914 if (bHighlight)
916 if (pEntry->mbEnabled)
918 rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuHighlightColor());
920 else
922 rRenderContext.SetFillColor();
923 oldLineColor = rRenderContext.GetLineColor();
924 rRenderContext.SetLineColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuHighlightColor());
925 bRestoreLineColor = true;
928 else
930 rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuColor());
932 rRenderContext.DrawRect(aItemRect);
934 implPaint(rRenderContext, pEntry, bHighlight);
935 if (bRestoreLineColor)
936 rRenderContext.SetLineColor(oldLineColor);
937 break;
940 nY += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
946 void ToolbarMenu::implSelectEntry( int nSelectedEntry )
948 mpImpl->mnSelectedEntry = nSelectedEntry;
950 ToolbarMenuEntry* pEntry = NULL;
951 if( nSelectedEntry != -1 )
952 pEntry = mpImpl->maEntryVector[ nSelectedEntry ];
954 if( pEntry )
955 mpImpl->maSelectHdl.Call( this );
960 void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt )
962 implHighlightAtPosition(rMEvt, true);
963 implSelectEntry(mpImpl->mnHighlightedEntry);
968 void ToolbarMenu::MouseButtonUp( const MouseEvent& )
974 void ToolbarMenu::MouseMove( const MouseEvent& rMEvt )
976 if (!IsVisible())
977 return;
979 implHighlightAtPosition(rMEvt, false);
984 void ToolbarMenu::implHighlightAtPosition(const MouseEvent& rMEvt, bool /*bMBDown*/)
986 long nMouseY = rMEvt.GetPosPixel().Y();
987 Size aOutSz = GetOutputSizePixel();
988 if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) )
990 long nY = 0;
991 bool bHighlighted = false;
993 const int nEntryCount = mpImpl->maEntryVector.size();
994 int nEntry;
995 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
997 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
998 if( pEntry )
1000 long nOldY = nY;
1001 nY += pEntry->maSize.Height();
1003 if( pEntry->mnEntryId != TITLE_ID )
1005 if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
1007 if( nEntry != mpImpl->mnHighlightedEntry )
1009 implChangeHighlightEntry( nEntry );
1011 bHighlighted = true;
1015 else
1017 nY += SEPARATOR_HEIGHT;
1020 if ( !bHighlighted )
1021 implChangeHighlightEntry( -1 );
1023 else
1025 implChangeHighlightEntry( -1 );
1031 void ToolbarMenu::implChangeHighlightEntry(int nEntry)
1033 mpImpl->mnHighlightedEntry = nEntry;
1034 Invalidate();
1036 mpImpl->notifyHighlightedEntry();
1041 static bool implCheckSubControlCursorMove( Control* pControl, bool bUp, int& nLastColumn )
1043 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
1044 if( pValueSet )
1046 size_t nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() );
1047 if( nItemPos != VALUESET_ITEM_NOTFOUND )
1049 const sal_uInt16 nColCount = pValueSet->GetColCount();
1050 const size_t nLine = nItemPos / nColCount;
1052 nLastColumn = nItemPos - (nLine * nColCount);
1054 if( bUp )
1056 return nLine > 0;
1058 else
1060 const size_t nLineCount = (pValueSet->GetItemCount() + nColCount - 1) / nColCount;
1061 return (nLine+1) < nLineCount;
1066 return false;
1071 ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd )
1073 int n = 0, nLoop = 0;
1074 if( !bHomeEnd )
1076 n = mpImpl->mnHighlightedEntry;
1077 if( n == -1 )
1079 if( bUp )
1080 n = 0;
1081 else
1082 n = mpImpl->maEntryVector.size()-1;
1084 else
1086 // if we have a currently selected entry and
1087 // cursor keys are used than check if this entry
1088 // has a control that can use those cursor keys
1089 ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
1090 if( pData && pData->mpControl && !pData->mbHasText )
1092 if( implCheckSubControlCursorMove( pData->mpControl, bUp, mpImpl->mnLastColumn ) )
1093 return pData;
1096 nLoop = n;
1098 else
1100 // absolute positioning
1101 if( bUp )
1103 n = mpImpl->maEntryVector.size();
1104 nLoop = n-1;
1106 else
1108 n = -1;
1109 nLoop = mpImpl->maEntryVector.size()-1;
1115 if( bUp )
1117 if ( n )
1118 n--;
1119 else
1120 if( mpImpl->mnHighlightedEntry == -1 )
1121 n = mpImpl->maEntryVector.size()-1;
1122 else
1123 break;
1125 else
1127 if( n < ((int)mpImpl->maEntryVector.size()-1) )
1128 n++;
1129 else
1130 if( mpImpl->mnHighlightedEntry == -1 )
1131 n = 0;
1132 else
1133 break;
1136 ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
1137 if( pData && (pData->mnEntryId != TITLE_ID) )
1139 implChangeHighlightEntry( n );
1140 return pData;
1142 } while ( n != nLoop );
1144 return 0;
1149 void ToolbarMenu_Impl::implHighlightControl( sal_uInt16 nCode, Control* pControl )
1151 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
1152 if( pValueSet )
1154 const size_t nItemCount = pValueSet->GetItemCount();
1155 size_t nItemPos = VALUESET_ITEM_NOTFOUND;
1156 switch( nCode )
1158 case KEY_UP:
1160 const sal_uInt16 nColCount = pValueSet->GetColCount();
1161 const sal_uInt16 nLastLine = nItemCount / nColCount;
1162 nItemPos = std::min( static_cast<size_t>(((nLastLine-1) * nColCount) + mnLastColumn), nItemCount-1 );
1163 break;
1165 case KEY_DOWN:
1166 nItemPos = std::min( static_cast<size_t>(mnLastColumn), nItemCount-1 );
1167 break;
1168 case KEY_END:
1169 nItemPos = nItemCount -1;
1170 break;
1171 case KEY_HOME:
1172 nItemPos = 0;
1173 break;
1175 pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) );
1176 notifyHighlightedEntry();
1182 void ToolbarMenu::KeyInput( const KeyEvent& rKEvent )
1184 Control* pForwardControl = 0;
1185 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
1186 switch ( nCode )
1188 case KEY_UP:
1189 case KEY_DOWN:
1191 int nOldEntry = mpImpl->mnHighlightedEntry;
1192 ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false );
1193 if( p && p->mpControl )
1195 if( nOldEntry != mpImpl->mnHighlightedEntry )
1197 mpImpl->implHighlightControl( nCode, p->mpControl );
1199 else
1201 // in case we are in a system floating window, GrabFocus does not work :-/
1202 pForwardControl = p->mpControl;
1206 break;
1207 case KEY_END:
1208 case KEY_HOME:
1210 ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true );
1211 if( p && p->mpControl )
1213 mpImpl->implHighlightControl( nCode, p->mpControl );
1216 break;
1217 case KEY_F6:
1218 case KEY_ESCAPE:
1220 // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
1221 if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
1222 break;
1224 implSelectEntry( -1 );
1226 break;
1228 case KEY_RETURN:
1230 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
1231 if ( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
1233 if( pEntry->mpControl )
1235 pForwardControl = pEntry->mpControl;
1237 else
1239 implSelectEntry( mpImpl->mnHighlightedEntry );
1243 break;
1244 default:
1246 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
1247 if ( pEntry && pEntry->mbEnabled && pEntry->mpControl && !pEntry->mbHasText )
1249 pForwardControl = pEntry->mpControl;
1254 if( pForwardControl )
1255 pForwardControl->KeyInput( rKEvent );
1260 static void ImplPaintCheckBackground(vcl::RenderContext& rRenderContext, vcl::Window& rWindow, const Rectangle& i_rRect, bool i_bHighlight )
1262 bool bNativeOk = false;
1263 if (rRenderContext.IsNativeControlSupported(CTRL_TOOLBAR, PART_BUTTON))
1265 ImplControlValue aControlValue;
1266 ControlState nState = ControlState::PRESSED | ControlState::ENABLED;
1268 aControlValue.setTristateVal(BUTTONVALUE_ON);
1270 bNativeOk = rRenderContext.DrawNativeControl(CTRL_TOOLBAR, PART_BUTTON,
1271 i_rRect, nState, aControlValue, OUString());
1274 if (!bNativeOk)
1276 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1277 Color aColor(i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor());
1278 vcl::RenderTools::DrawSelectionBackground(rRenderContext, rWindow, i_rRect, 0, i_bHighlight, true, false, NULL, 2, &aColor);
1282 void ToolbarMenu::implPaint(vcl::RenderContext& rRenderContext, ToolbarMenuEntry* pThisOnly, bool bHighlighted)
1284 sal_uInt16 nBorder = 0; long nStartY = 0; // from Menu implementations, needed when we support native menu background & scrollable menu
1286 long nFontHeight = GetTextHeight();
1288 long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
1289 ImplGetNativeCheckAndRadioSize(rRenderContext, nCheckHeight, nRadioHeight, nMaxCheckWidth);
1291 DecorationView aDecoView(&rRenderContext);
1292 const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
1293 const bool bUseImages = rSettings.GetUseImagesInMenus();
1295 int nOuterSpace = 0; // ImplGetSVData()->maNWFData.mnMenuFormatExtraBorder;
1296 Point aTopLeft(nOuterSpace, nOuterSpace), aTmpPos;
1298 Size aOutSz(GetOutputSizePixel());
1299 const int nEntryCount = mpImpl->maEntryVector.size();
1300 int nEntry;
1301 for (nEntry = 0; nEntry < nEntryCount; nEntry++)
1303 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
1305 Point aPos(aTopLeft);
1306 aPos.Y() += nBorder;
1307 aPos.Y() += nStartY;
1309 if ((pEntry == 0) && !pThisOnly)
1311 // Separator
1312 aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT - 2) / 2);
1313 aTmpPos.X() = aPos.X() + 2 + nOuterSpace;
1314 rRenderContext.SetLineColor(rSettings.GetShadowColor());
1315 rRenderContext.DrawLine(aTmpPos, Point(aOutSz.Width() - 3 - 2 * nOuterSpace, aTmpPos.Y()));
1316 aTmpPos.Y()++;
1317 rRenderContext.SetLineColor(rSettings.GetLightColor());
1318 rRenderContext.DrawLine(aTmpPos, Point( aOutSz.Width() - 3 - 2 * nOuterSpace, aTmpPos.Y()));
1319 rRenderContext.SetLineColor();
1321 else if (!pThisOnly || (pEntry == pThisOnly))
1323 const bool bTitle = pEntry->mnEntryId == TITLE_ID;
1325 if (pThisOnly && bHighlighted)
1326 rRenderContext.SetTextColor(rSettings.GetMenuHighlightTextColor());
1328 if( aPos.Y() >= 0 )
1330 long nTextOffsetY = ((pEntry->maSize.Height() - nFontHeight) / 2);
1332 DrawTextFlags nTextStyle = DrawTextFlags::NONE;
1333 DrawSymbolFlags nSymbolStyle = DrawSymbolFlags::NONE;
1334 DrawImageFlags nImageStyle = DrawImageFlags::NONE;
1336 if (!pEntry->mbEnabled)
1338 nTextStyle |= DrawTextFlags::Disable;
1339 nSymbolStyle |= DrawSymbolFlags::Disable;
1340 nImageStyle |= DrawImageFlags::Disable;
1343 Rectangle aOuterCheckRect(Point(aPos.X() + mpImpl->mnCheckPos, aPos.Y()),
1344 Size(pEntry->maSize.Height(), pEntry->maSize.Height()));
1345 aOuterCheckRect.Left() += 1;
1346 aOuterCheckRect.Right() -= 1;
1347 aOuterCheckRect.Top() += 1;
1348 aOuterCheckRect.Bottom() -= 1;
1350 if (bTitle)
1352 // fill the background
1353 Rectangle aRect(aTopLeft, Size(aOutSz.Width(), pEntry->maSize.Height()));
1354 rRenderContext.SetFillColor(rSettings.GetDialogColor());
1355 rRenderContext.SetLineColor();
1356 rRenderContext.DrawRect(aRect);
1357 rRenderContext.SetLineColor(rSettings.GetLightColor());
1358 rRenderContext.DrawLine(aRect.TopLeft(), aRect.TopRight());
1359 rRenderContext.SetLineColor(rSettings.GetShadowColor());
1360 rRenderContext.DrawLine(aRect.BottomLeft(), aRect.BottomRight());
1363 // CheckMark
1364 if (pEntry->HasCheck())
1366 // draw selection transparent marker if checked
1367 // onto that either a checkmark or the item image
1368 // will be painted
1369 // however do not do this if native checks will be painted since
1370 // the selection color too often does not fit the theme's check and/or radio
1372 if (!pEntry->mbHasImage)
1374 if (rRenderContext.IsNativeControlSupported(CTRL_MENU_POPUP,
1375 (pEntry->mnBits & MenuItemBits::RADIOCHECK)
1376 ? PART_MENU_ITEM_CHECK_MARK
1377 : PART_MENU_ITEM_RADIO_MARK))
1379 ControlPart nPart = ((pEntry->mnBits & MenuItemBits::RADIOCHECK)
1380 ? PART_MENU_ITEM_RADIO_MARK
1381 : PART_MENU_ITEM_CHECK_MARK);
1383 ControlState nState = ControlState::NONE;
1385 if (pEntry->mbChecked)
1386 nState |= ControlState::PRESSED;
1388 if (pEntry->mbEnabled)
1389 nState |= ControlState::ENABLED;
1391 if ( bHighlighted )
1392 nState |= ControlState::SELECTED;
1394 long nCtrlHeight = (pEntry->mnBits & MenuItemBits::RADIOCHECK) ? nCheckHeight : nRadioHeight;
1395 aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight) / 2;
1396 aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight) / 2;
1398 Rectangle aCheckRect(aTmpPos, Size(nCtrlHeight, nCtrlHeight));
1399 rRenderContext.DrawNativeControl(CTRL_MENU_POPUP, nPart, aCheckRect,
1400 nState, ImplControlValue(), OUString());
1401 aPos.setX(aPos.getX() + nCtrlHeight + gfxExtra);
1403 else if (pEntry->mbChecked) // by default do nothing for unchecked items
1405 ImplPaintCheckBackground(rRenderContext, *this, aOuterCheckRect, pThisOnly && bHighlighted);
1407 SymbolType eSymbol;
1408 Size aSymbolSize;
1409 if (pEntry->mnBits & MenuItemBits::RADIOCHECK)
1411 eSymbol = SymbolType::RADIOCHECKMARK;
1412 aSymbolSize = Size(nFontHeight / 2, nFontHeight / 2);
1414 else
1416 eSymbol = SymbolType::CHECKMARK;
1417 aSymbolSize = Size((nFontHeight * 25) / 40, nFontHeight / 2);
1419 aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2;
1420 aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2;
1421 Rectangle aRect( aTmpPos, aSymbolSize );
1422 aDecoView.DrawSymbol(aRect, eSymbol, GetTextColor(), nSymbolStyle);
1423 aPos.setX(aPos.getX() + aSymbolSize.getWidth( ) + gfxExtra);
1428 // Image:
1429 if (pEntry->mbHasImage && bUseImages)
1431 if (pEntry->mbChecked)
1432 ImplPaintCheckBackground(rRenderContext, *this, aOuterCheckRect, pThisOnly && bHighlighted);
1433 aTmpPos = aOuterCheckRect.TopLeft();
1434 aTmpPos.X() += (aOuterCheckRect.GetWidth()-pEntry->maImage.GetSizePixel().Width())/2;
1435 aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pEntry->maImage.GetSizePixel().Height())/2;
1436 rRenderContext.DrawImage( aTmpPos, pEntry->maImage, nImageStyle );
1439 // Text:
1440 if (pEntry->mbHasText)
1442 aTmpPos.X() = aPos.X() + (bTitle ? 4 : mpImpl->mnTextPos);
1443 aTmpPos.Y() = aPos.Y();
1444 aTmpPos.Y() += nTextOffsetY;
1445 DrawTextFlags nStyle = nTextStyle|DrawTextFlags::Mnemonic;
1447 rRenderContext.DrawCtrlText(aTmpPos, pEntry->maText, 0, pEntry->maText.getLength(), nStyle, NULL, NULL);
1450 if (pThisOnly && bHighlighted)
1452 // This restores the normal menu or menu bar text
1453 // color for when it is no longer highlighted.
1454 rRenderContext.SetTextColor(rSettings.GetMenuTextColor());
1459 aTopLeft.Y() += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
1463 void ToolbarMenu::Paint(vcl::RenderContext& rRenderContext, const Rectangle&)
1465 rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetMenuColor());
1467 implPaint(rRenderContext);
1469 if (mpImpl->mnHighlightedEntry != -1)
1470 implHighlightEntry(rRenderContext, mpImpl->mnHighlightedEntry, true);
1475 void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt )
1477 DockingWindow::RequestHelp( rHEvt );
1482 void ToolbarMenu::StateChanged( StateChangedType nType )
1484 DockingWindow::StateChanged( nType );
1486 if ( ( nType == StateChangedType::ControlForeground ) || ( nType == StateChangedType::ControlBackground ) )
1488 initWindow();
1489 Invalidate();
1495 void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt )
1497 DockingWindow::DataChanged( rDCEvt );
1499 if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1500 (rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
1501 ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1502 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1504 initWindow();
1505 Invalidate();
1511 void ToolbarMenu::Command( const CommandEvent& rCEvt )
1513 if ( rCEvt.GetCommand() == CommandEventId::Wheel )
1515 const CommandWheelData* pData = rCEvt.GetWheelData();
1516 if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
1518 implCursorUpDown( pData->GetDelta() > 0L, false );
1525 Reference< ::com::sun::star::accessibility::XAccessible > ToolbarMenu::CreateAccessible()
1527 mpImpl->setAccessible( new ToolbarMenuAcc( *mpImpl ) );
1528 return Reference< XAccessible >( mpImpl->mxAccessible.get() );
1533 // todo: move to new base class that will replace SfxPopupWindo
1534 void ToolbarMenu::AddStatusListener( const OUString& rCommandURL )
1536 initStatusListener();
1537 mpImpl->mxStatusListener->addStatusListener( rCommandURL );
1542 void ToolbarMenu::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& /*Event*/ ) throw ( ::com::sun::star::uno::RuntimeException )
1548 class ToolbarMenuStatusListener : public svt::FrameStatusListener
1550 public:
1551 ToolbarMenuStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
1552 ToolbarMenu& rToolbarMenu );
1554 virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
1555 virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
1557 VclPtr<ToolbarMenu> mpMenu;
1562 ToolbarMenuStatusListener::ToolbarMenuStatusListener(
1563 const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
1564 ToolbarMenu& rToolbarMenu )
1565 : svt::FrameStatusListener( ::comphelper::getProcessComponentContext(), xFrame )
1566 , mpMenu( &rToolbarMenu )
1572 void SAL_CALL ToolbarMenuStatusListener::dispose() throw (::com::sun::star::uno::RuntimeException, std::exception)
1574 mpMenu.clear();
1575 svt::FrameStatusListener::dispose();
1580 void SAL_CALL ToolbarMenuStatusListener::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException, std::exception )
1582 if( mpMenu )
1583 mpMenu->statusChanged( Event );
1588 void ToolbarMenu::initStatusListener()
1590 if( !mpImpl->mxStatusListener.is() )
1591 mpImpl->mxStatusListener.set( new ToolbarMenuStatusListener( mpImpl->mxFrame, *this ) );
1596 bool ToolbarMenu::IsInPopupMode()
1598 return GetDockingManager()->IsInPopupMode(this);
1603 void ToolbarMenu::EndPopupMode()
1605 GetDockingManager()->EndPopupMode(this);
1610 const Size& ToolbarMenu::getMenuSize() const
1612 return mpImpl->maSize;
1617 void ToolbarMenu::SetSelectHdl( const Link<>& rLink )
1619 mpImpl->maSelectHdl = rLink;
1627 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */