update credits
[LibreOffice.git] / svtools / source / control / toolbarmenu.cxx
blob3405dac90448437931d1cd688a1aeebf06216dbe
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>
30 #include "svtools/valueset.hxx"
31 #include "svtools/toolbarmenu.hxx"
32 #include "toolbarmenuimp.hxx"
34 using namespace ::com::sun::star::uno;
35 using namespace ::com::sun::star::lang;
36 using namespace ::com::sun::star::frame;
37 using namespace ::com::sun::star::accessibility;
39 namespace svtools {
41 // --------------------------------------------------------------------
43 static Window* GetTopMostParentSystemWindow( Window* pWindow )
45 OSL_ASSERT( pWindow );
46 if ( pWindow )
48 // ->manually search topmost system window
49 // required because their might be another system window between this and the top window
50 pWindow = pWindow->GetParent();
51 SystemWindow* pTopMostSysWin = NULL;
52 while ( pWindow )
54 if ( pWindow->IsSystemWindow() )
55 pTopMostSysWin = (SystemWindow*)pWindow;
56 pWindow = pWindow->GetParent();
58 pWindow = pTopMostSysWin;
59 OSL_ASSERT( pWindow );
60 return pWindow;
63 return NULL;
66 // --------------------------------------------------------------------
68 void ToolbarMenuEntry::init( int nEntryId, MenuItemBits nBits )
70 mnEntryId = nEntryId;
71 mnBits = nBits;
73 mbHasText = false;
74 mbHasImage = false;
75 mbChecked = false;
76 mbEnabled = true;
78 mpControl = NULL;
81 // --------------------------------------------------------------------
83 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits )
84 : mrMenu( rMenu )
86 init( nEntryId, nBits );
88 maText = rText;
89 mbHasText = true;
92 // --------------------------------------------------------------------
94 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits )
95 : mrMenu( rMenu )
97 init( nEntryId, nBits );
99 maText = rText;
100 mbHasText = true;
102 maImage = rImage;
103 mbHasImage = true;
106 // --------------------------------------------------------------------
108 ToolbarMenuEntry::ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits )
109 : mrMenu( rMenu )
111 init( nEntryId, nBits );
113 if( pControl )
115 mpControl = pControl;
116 mpControl->Show();
120 // --------------------------------------------------------------------
122 ToolbarMenuEntry::~ToolbarMenuEntry()
124 if( mxAccContext.is() )
126 Reference< XComponent > xComponent( mxAccContext, UNO_QUERY );
127 if( xComponent.is() )
128 xComponent->dispose();
129 mxAccContext.clear();
131 delete mpControl;
134 // --------------------------------------------------------------------
136 const Reference< XAccessibleContext >& ToolbarMenuEntry::GetAccessible( bool bCreate /* = false */ )
138 if( !mxAccContext.is() && bCreate )
140 if( mpControl )
142 mxAccContext = Reference< XAccessibleContext >( mpControl->GetAccessible( sal_True ), UNO_QUERY );
144 else
146 mxAccContext = Reference< XAccessibleContext >( new ToolbarMenuEntryAcc( this ) );
150 return mxAccContext;
153 // --------------------------------------------------------------------
155 sal_Int32 ToolbarMenuEntry::getAccessibleChildCount() throw (RuntimeException)
157 if( mpControl )
159 const Reference< XAccessibleContext >& xContext = GetAccessible( true );
160 if( xContext.is() )
162 return xContext->getAccessibleChildCount();
165 return 1;
168 // --------------------------------------------------------------------
170 Reference< XAccessible > ToolbarMenuEntry::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
172 const Reference< XAccessibleContext >& xContext = GetAccessible( true );
173 if( mpControl )
175 if( xContext.is() )
177 return xContext->getAccessibleChild(index);
180 else if( index == 0 )
182 Reference< XAccessible > xRet( xContext, UNO_QUERY );
183 if( xRet.is() )
184 return xRet;
187 throw IndexOutOfBoundsException();
190 // --------------------------------------------------------------------
192 ToolbarMenu_Impl::ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame )
193 : mrMenu( rMenu )
194 , mxFrame( xFrame )
195 , mnCheckPos(0)
196 , mnImagePos(0)
197 , mnTextPos(0)
198 , mnHighlightedEntry(-1)
199 , mnSelectedEntry(-1)
200 , mnLastColumn(0)
204 // --------------------------------------------------------------------
206 ToolbarMenu_Impl::~ToolbarMenu_Impl()
208 setAccessible( 0 );
211 // --------------------------------------------------------------------
213 void ToolbarMenu_Impl::setAccessible( ToolbarMenuAcc* pAccessible )
215 if( mxAccessible.get() != pAccessible )
217 if( mxAccessible.is() )
218 mxAccessible->dispose();
220 mxAccessible.set( pAccessible );
224 // -----------------------------------------------------------------------
226 void ToolbarMenu_Impl::fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue )
228 if( mxAccessible.is() )
229 mxAccessible->FireAccessibleEvent( nEventId, rOldValue, rNewValue );
232 // -----------------------------------------------------------------------
234 bool ToolbarMenu_Impl::hasAccessibleListeners()
236 return( mxAccessible.is() && mxAccessible->HasAccessibleListeners() );
239 // --------------------------------------------------------------------
241 sal_Int32 ToolbarMenu_Impl::getAccessibleChildCount() throw (RuntimeException)
243 sal_Int32 nCount = 0;
244 const int nEntryCount = maEntryVector.size();
245 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
247 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
248 if( pEntry )
250 if( pEntry->mpControl )
252 nCount += pEntry->getAccessibleChildCount();
254 else
256 nCount += 1;
261 return nCount;
264 // --------------------------------------------------------------------
266 Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( sal_Int32 index ) throw (IndexOutOfBoundsException, RuntimeException)
268 const int nEntryCount = maEntryVector.size();
269 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
271 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
272 if( pEntry )
274 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
275 if( index < nCount )
277 return pEntry->getAccessibleChild( index );
279 index -= nCount;
283 throw IndexOutOfBoundsException();
286 // --------------------------------------------------------------------
288 Reference< XAccessible > ToolbarMenu_Impl::getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (IndexOutOfBoundsException, RuntimeException)
290 const int nEntryCount = maEntryVector.size();
291 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
293 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
294 if( pEntry && (pEntry->mpControl == pControl) )
296 return pEntry->getAccessibleChild( childIndex );
300 throw IndexOutOfBoundsException();
303 // --------------------------------------------------------------------
305 void ToolbarMenu_Impl::selectAccessibleChild( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
307 const int nEntryCount = maEntryVector.size();
308 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
310 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
311 if( pEntry )
313 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
314 if( nChildIndex < nCount )
316 if( pEntry->mpControl )
318 Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
319 xSel->selectAccessibleChild(nChildIndex);
321 else if( pEntry->mnEntryId != TITLE_ID )
323 mrMenu.implSelectEntry( nEntry );
325 return;
327 nChildIndex -= nCount;
331 throw IndexOutOfBoundsException();
334 // --------------------------------------------------------------------
336 sal_Bool ToolbarMenu_Impl::isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (IndexOutOfBoundsException, RuntimeException)
338 const int nEntryCount = maEntryVector.size();
339 for( int nEntry = 0; nEntry < nEntryCount; nEntry++ )
341 ToolbarMenuEntry* pEntry = maEntryVector[nEntry];
342 if( pEntry )
344 const sal_Int32 nCount = pEntry->getAccessibleChildCount();
345 if( nChildIndex < nCount )
347 if( mnHighlightedEntry == nEntry )
349 if( pEntry->mpControl )
351 Reference< XAccessibleSelection > xSel( pEntry->GetAccessible(true), UNO_QUERY_THROW );
352 xSel->isAccessibleChildSelected(nChildIndex);
354 return true;
356 else
358 return false;
361 nChildIndex -= nCount;
365 throw IndexOutOfBoundsException();
368 // --------------------------------------------------------------------
370 void ToolbarMenu_Impl::clearAccessibleSelection()
372 if( mnHighlightedEntry != -1 )
374 mrMenu.implHighlightEntry( mnHighlightedEntry, false );
375 mnHighlightedEntry = -1;
380 // --------------------------------------------------------------------
382 void ToolbarMenu_Impl::notifyHighlightedEntry()
384 if( hasAccessibleListeners() )
386 ToolbarMenuEntry* pEntry = implGetEntry( mnHighlightedEntry );
387 if( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
389 Any aNew;
390 Any aOld( mxOldSelection );
391 if( pEntry->mpControl )
393 sal_Int32 nChildIndex = 0;
394 // todo: if other controls than ValueSet are allowed, addapt this code
395 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
396 if( pValueSet )
397 nChildIndex = static_cast< sal_Int32 >( pValueSet->GetItemPos( pValueSet->GetSelectItemId() ) );
399 if( nChildIndex >= pEntry->getAccessibleChildCount() )
400 return;
402 aNew <<= getAccessibleChild( pEntry->mpControl, nChildIndex );
404 else
406 aNew <<= pEntry->GetAccessible(true);
409 fireAccessibleEvent( AccessibleEventId::ACTIVE_DESCENDANT_CHANGED, aOld, aNew );
410 fireAccessibleEvent( AccessibleEventId::SELECTION_CHANGED, aOld, aNew );
411 fireAccessibleEvent( AccessibleEventId::STATE_CHANGED, Any(), Any( AccessibleStateType::FOCUSED ) );
412 aNew >>= mxOldSelection;
417 // --------------------------------------------------------------------
419 ToolbarMenuEntry* ToolbarMenu_Impl::implGetEntry( int nEntry ) const
421 if( (nEntry < 0) || (nEntry >= (int)maEntryVector.size() ) )
422 return NULL;
424 return maEntryVector[nEntry];
428 // --------------------------------------------------------------------
430 IMPL_LINK( ToolbarMenu, HighlightHdl, Control *, pControl )
432 (void)pControl;
433 mpImpl->notifyHighlightedEntry();
434 return 0;
437 // ====================================================================
439 ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, WinBits nBits )
440 : DockingWindow(pParentWindow, nBits)
442 implInit(rFrame);
445 // --------------------------------------------------------------------
447 ToolbarMenu::ToolbarMenu( const Reference< XFrame >& rFrame, Window* pParentWindow, const ResId& rResId )
448 : DockingWindow(pParentWindow, rResId)
450 implInit(rFrame);
453 // --------------------------------------------------------------------
455 void ToolbarMenu::implInit(const Reference< XFrame >& rFrame)
457 mpImpl = new ToolbarMenu_Impl( *this, rFrame );
459 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
460 SetControlBackground( rStyleSettings.GetMenuColor() );
462 initWindow();
464 Window* pWindow = GetTopMostParentSystemWindow( this );
465 if ( pWindow )
466 ((SystemWindow *)pWindow)->GetTaskPaneList()->AddWindow( this );
469 // --------------------------------------------------------------------
471 ToolbarMenu::~ToolbarMenu()
473 Window* pWindow = GetTopMostParentSystemWindow( this );
474 if ( pWindow )
475 ((SystemWindow *)pWindow)->GetTaskPaneList()->RemoveWindow( this );
477 if ( mpImpl->mxStatusListener.is() )
479 mpImpl->mxStatusListener->dispose();
480 mpImpl->mxStatusListener.clear();
483 // delete all menu entries
484 const int nEntryCount = mpImpl->maEntryVector.size();
485 int nEntry;
486 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
488 delete mpImpl->maEntryVector[nEntry];
491 delete mpImpl;
494 // --------------------------------------------------------------------
496 int ToolbarMenu::getSelectedEntryId() const
498 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnSelectedEntry );
499 return pEntry ? pEntry->mnEntryId : -1;
502 // --------------------------------------------------------------------
504 int ToolbarMenu::getHighlightedEntryId() const
506 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
507 return pEntry ? pEntry->mnEntryId : -1;
510 // --------------------------------------------------------------------
512 void ToolbarMenu::checkEntry( int nEntryId, bool bChecked )
514 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
515 if( pEntry && pEntry->mbChecked != bChecked )
517 pEntry->mbChecked = bChecked;
518 Invalidate();
522 // --------------------------------------------------------------------
524 void ToolbarMenu::enableEntry( int nEntryId, bool bEnable )
526 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
527 if( pEntry && pEntry->mbEnabled != bEnable )
529 pEntry->mbEnabled = bEnable;
530 if( pEntry->mpControl )
532 pEntry->mpControl->Enable( bEnable );
534 // hack for the valueset to make it paint itself anew
535 pEntry->mpControl->Resize();
537 Invalidate();
541 // --------------------------------------------------------------------
543 void ToolbarMenu::setEntryText( int nEntryId, const String& rStr )
545 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
546 if( pEntry && pEntry->maText != rStr )
548 pEntry->maText = rStr;
549 mpImpl->maSize = implCalcSize();
550 if( IsVisible() )
551 Invalidate();
555 // --------------------------------------------------------------------
557 void ToolbarMenu::setEntryImage( int nEntryId, const Image& rImage )
559 ToolbarMenuEntry* pEntry = implSearchEntry( nEntryId );
560 if( pEntry && pEntry->maImage != rImage )
562 pEntry->maImage = rImage;
563 mpImpl->maSize = implCalcSize();
564 if( IsVisible() )
565 Invalidate();
569 // --------------------------------------------------------------------
571 void ToolbarMenu::initWindow()
573 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
575 SetPointFont( rStyleSettings.GetMenuFont() );
576 SetBackground( Wallpaper( GetControlBackground() ) );
577 SetTextColor( rStyleSettings.GetMenuTextColor() );
578 SetTextFillColor();
579 SetLineColor();
581 mpImpl->maSize = implCalcSize();
584 // --------------------------------------------------------------------
586 static long ImplGetNativeCheckAndRadioSize( Window* pWin, long& rCheckHeight, long& rRadioHeight, long &rMaxWidth )
588 rMaxWidth = rCheckHeight = rRadioHeight = 0;
590 ImplControlValue aVal;
591 Rectangle aNativeBounds;
592 Rectangle aNativeContent;
593 Point tmp( 0, 0 );
594 Rectangle aCtrlRegion( tmp, Size( 100, 15 ) );
595 if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_CHECK_MARK ) )
597 if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
598 ControlPart(PART_MENU_ITEM_CHECK_MARK),
599 aCtrlRegion,
600 ControlState(CTRL_STATE_ENABLED),
601 aVal,
602 OUString(),
603 aNativeBounds,
604 aNativeContent )
607 rCheckHeight = aNativeBounds.GetHeight();
608 rMaxWidth = aNativeContent.GetWidth();
611 if( pWin->IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM_RADIO_MARK ) )
613 if( pWin->GetNativeControlRegion( ControlType(CTRL_MENU_POPUP),
614 ControlPart(PART_MENU_ITEM_RADIO_MARK),
615 aCtrlRegion,
616 ControlState(CTRL_STATE_ENABLED),
617 aVal,
618 OUString(),
619 aNativeBounds,
620 aNativeContent )
623 rRadioHeight = aNativeBounds.GetHeight();
624 rMaxWidth = std::max (rMaxWidth, aNativeContent.GetWidth());
627 return (rCheckHeight > rRadioHeight) ? rCheckHeight : rRadioHeight;
630 #define gfxExtra 7
632 Size ToolbarMenu::implCalcSize()
634 const long nFontHeight = GetTextHeight();
635 long nExtra = nFontHeight/4;
637 Size aSz;
638 Size aMaxImgSz;
639 long nMaxTextWidth = 0;
640 long nMinMenuItemHeight = nFontHeight+2;
641 sal_Bool bCheckable = sal_False;
643 const int nEntryCount = mpImpl->maEntryVector.size();
644 int nEntry;
646 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
647 const bool bUseImages = rSettings.GetUseImagesInMenus();
649 // get maximum image size
650 if( bUseImages )
652 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
654 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
655 if( pEntry && pEntry->mbHasImage )
657 Size aImgSz( pEntry->maImage.GetSizePixel() );
658 nMinMenuItemHeight = std::max( nMinMenuItemHeight, aImgSz.Height() + 6 );
659 aMaxImgSz.Width() = std::max( aMaxImgSz.Width(), aImgSz.Width() );
664 mpImpl->mnCheckPos = nExtra;
665 mpImpl->mnImagePos = nExtra;
666 mpImpl->mnTextPos = mpImpl->mnImagePos + aMaxImgSz.Width();
668 if ( aMaxImgSz.Width() )
669 mpImpl->mnTextPos += std::max( nExtra, 7L );
670 if ( bCheckable )
671 mpImpl->mnTextPos += 16;
673 // set heights, calc maximum width
674 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
676 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
678 if( pEntry )
680 if ( ( pEntry->mnBits ) & ( MIB_RADIOCHECK | MIB_CHECKABLE ) )
681 bCheckable = sal_True;
683 // Text:
684 if( pEntry->mbHasText || pEntry->mbHasImage )
686 pEntry->maSize.Height() = nMinMenuItemHeight;
688 if( pEntry->mbHasText )
690 long nTextWidth = GetCtrlTextWidth( pEntry->maText ) + mpImpl->mnTextPos + nExtra;
691 nMaxTextWidth = std::max( nTextWidth, nMaxTextWidth );
694 // Control:
695 else if( pEntry->mpControl )
697 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
699 nMaxTextWidth = std::max( aControlSize.Width(), nMaxTextWidth );
700 pEntry->maSize.Height() = aControlSize.Height() + 1;
703 if( pEntry->HasCheck() && !pEntry->mbHasImage )
705 if( this->IsNativeControlSupported( CTRL_MENU_POPUP,
706 (pEntry->mnBits & MIB_RADIOCHECK)
707 ? PART_MENU_ITEM_CHECK_MARK
708 : PART_MENU_ITEM_RADIO_MARK ) )
710 long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
711 ImplGetNativeCheckAndRadioSize( this, nCheckHeight, nRadioHeight, nMaxCheckWidth );
713 long nCtrlHeight = (pEntry->mnBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight;
714 nMaxTextWidth += nCtrlHeight + gfxExtra;
716 else if( pEntry->mbChecked )
718 long nSymbolWidth = (nFontHeight*25)/40;
719 if ( pEntry->mnBits & MIB_RADIOCHECK )
720 nSymbolWidth = nFontHeight/2;
722 nMaxTextWidth += nSymbolWidth;
728 aSz.Width() = nMaxTextWidth + (BORDER_X<<1);
730 // positionate controls
731 int nY = BORDER_Y;
732 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
734 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
736 if( pEntry )
738 pEntry->maSize.Width() = nMaxTextWidth;
740 if( pEntry->mpControl )
742 Size aControlSize( pEntry->mpControl->GetOutputSizePixel() );
743 Point aControlPos( (aSz.Width() - aControlSize.Width())>>1, nY);
745 pEntry->mpControl->SetPosPixel( aControlPos );
747 pEntry->maRect = Rectangle( aControlPos, aControlSize );
749 else
751 pEntry->maRect = Rectangle( Point( 0, nY ), pEntry->maSize );
754 nY += pEntry->maSize.Height();
756 else
758 nY += SEPARATOR_HEIGHT;
762 aSz.Height() += nY + BORDER_Y;
764 return aSz;
767 // --------------------------------------------------------------------
769 void ToolbarMenu::highlightFirstEntry()
771 implChangeHighlightEntry( 0 );
774 // --------------------------------------------------------------------
776 void ToolbarMenu::GetFocus()
778 if( mpImpl->mnHighlightedEntry == -1 )
779 implChangeHighlightEntry( 0 );
781 DockingWindow::GetFocus();
784 // --------------------------------------------------------------------
786 void ToolbarMenu::LoseFocus()
788 if( mpImpl->mnHighlightedEntry != -1 )
789 implChangeHighlightEntry( -1 );
791 DockingWindow::LoseFocus();
794 // --------------------------------------------------------------------
796 void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits )
798 appendEntry( new ToolbarMenuEntry( *this, nEntryId, rStr, nItemBits ) );
801 // --------------------------------------------------------------------
803 void ToolbarMenu::appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits )
805 appendEntry( new ToolbarMenuEntry( *this, nEntryId, rImage, rStr, nItemBits ) );
808 // --------------------------------------------------------------------
810 void ToolbarMenu::appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits )
812 appendEntry( new ToolbarMenuEntry( *this, nEntryId, pControl, nItemBits ) );
815 // --------------------------------------------------------------------
817 void ToolbarMenu::appendEntry( ToolbarMenuEntry* pEntry )
819 mpImpl->maEntryVector.push_back( pEntry );
820 mpImpl->maSize = implCalcSize();
821 if( IsVisible() )
822 Invalidate();
825 // --------------------------------------------------------------------
827 void ToolbarMenu::appendSeparator()
829 appendEntry( 0 );
832 // --------------------------------------------------------------------
834 /** creates an empty ValueSet that is initialized and can be inserted with appendEntry. */
835 ValueSet* ToolbarMenu::createEmptyValueSetControl()
837 ValueSet* pSet = new ValueSet( this, WB_TABSTOP | WB_MENUSTYLEVALUESET | WB_FLATVALUESET | WB_NOBORDER | WB_NO_DIRECTSELECT );
838 pSet->EnableFullItemMode( sal_False );
839 pSet->SetColor( GetControlBackground() );
840 pSet->SetHighlightHdl( LINK( this, ToolbarMenu, HighlightHdl ) );
841 return pSet;
844 // --------------------------------------------------------------------
846 ToolbarMenuEntry* ToolbarMenu::implGetEntry( int nEntry ) const
848 return mpImpl->implGetEntry( nEntry );
851 // --------------------------------------------------------------------
853 ToolbarMenuEntry* ToolbarMenu::implSearchEntry( int nEntryId ) const
855 const int nEntryCount = mpImpl->maEntryVector.size();
856 int nEntry;
857 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
859 ToolbarMenuEntry* p = mpImpl->maEntryVector[nEntry];
860 if( p && p->mnEntryId == nEntryId )
862 return p;
866 return NULL;
869 // --------------------------------------------------------------------
871 void ToolbarMenu::implHighlightEntry( int nHighlightEntry, bool bHighlight )
873 Size aSz( GetOutputSizePixel() );
874 long nX = 0, nY = 0;
876 const int nEntryCount = mpImpl->maEntryVector.size();
877 int nEntry;
878 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
880 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
881 if( pEntry && (nEntry == nHighlightEntry) )
883 // no highlights for controls only items
884 if( pEntry->mpControl )
886 if( !bHighlight )
888 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pEntry->mpControl );
889 if( pValueSet )
891 pValueSet->SetNoSelection();
894 break;
897 bool bRestoreLineColor = false;
898 Color oldLineColor;
899 bool bDrawItemRect = true;
901 Rectangle aItemRect( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) );
902 if ( pEntry->mnBits & MIB_POPUPSELECT )
904 long nFontHeight = GetTextHeight();
905 aItemRect.Right() -= nFontHeight + nFontHeight/4;
908 if( IsNativeControlSupported( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL ) )
910 Size aPxSize( GetOutputSizePixel() );
911 Push( PUSH_CLIPREGION );
912 IntersectClipRegion( Rectangle( Point( nX, nY ), Size( aSz.Width(), pEntry->maSize.Height() ) ) );
913 Rectangle aCtrlRect( Point( nX, 0 ), Size( aPxSize.Width()-nX, aPxSize.Height() ) );
914 DrawNativeControl( CTRL_MENU_POPUP, PART_ENTIRE_CONTROL,
915 aCtrlRect,
916 CTRL_STATE_ENABLED,
917 ImplControlValue(),
918 OUString() );
919 if( bHighlight && IsNativeControlSupported( CTRL_MENU_POPUP, PART_MENU_ITEM ) )
921 bDrawItemRect = false;
922 if( sal_False == DrawNativeControl( CTRL_MENU_POPUP, PART_MENU_ITEM,
923 aItemRect,
924 CTRL_STATE_SELECTED | ( pEntry->mbEnabled? CTRL_STATE_ENABLED: 0 ),
925 ImplControlValue(),
926 OUString() ) )
928 bDrawItemRect = bHighlight;
931 else
932 bDrawItemRect = bHighlight;
933 Pop();
935 if( bDrawItemRect )
937 if ( bHighlight )
939 if( pEntry->mbEnabled )
940 SetFillColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
941 else
943 SetFillColor();
944 oldLineColor = GetLineColor();
945 SetLineColor( GetSettings().GetStyleSettings().GetMenuHighlightColor() );
946 bRestoreLineColor = true;
949 else
950 SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
952 DrawRect( aItemRect );
954 implPaint( pEntry, bHighlight );
955 if( bRestoreLineColor )
956 SetLineColor( oldLineColor );
957 break;
960 nY += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
964 // --------------------------------------------------------------------
966 void ToolbarMenu::implSelectEntry( int nSelectedEntry )
968 mpImpl->mnSelectedEntry = nSelectedEntry;
970 ToolbarMenuEntry* pEntry = NULL;
971 if( nSelectedEntry != -1 )
972 pEntry = mpImpl->maEntryVector[ nSelectedEntry ];
974 if( pEntry )
975 mpImpl->maSelectHdl.Call( this );
978 // --------------------------------------------------------------------
980 void ToolbarMenu::MouseButtonDown( const MouseEvent& rMEvt )
982 implHighlightEntry( rMEvt, true );
984 implSelectEntry( mpImpl->mnHighlightedEntry );
987 // --------------------------------------------------------------------
989 void ToolbarMenu::MouseButtonUp( const MouseEvent& )
993 // --------------------------------------------------------------------
995 void ToolbarMenu::MouseMove( const MouseEvent& rMEvt )
997 if ( !IsVisible() )
998 return;
1000 implHighlightEntry( rMEvt, false );
1003 // --------------------------------------------------------------------
1005 void ToolbarMenu::implHighlightEntry( const MouseEvent& rMEvt, bool /*bMBDown*/ )
1007 long nY = 0;
1008 long nMouseY = rMEvt.GetPosPixel().Y();
1009 Size aOutSz = GetOutputSizePixel();
1010 if ( ( nMouseY >= 0 ) && ( nMouseY < aOutSz.Height() ) )
1012 bool bHighlighted = sal_False;
1014 const int nEntryCount = mpImpl->maEntryVector.size();
1015 int nEntry;
1016 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
1018 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
1019 if( pEntry )
1021 long nOldY = nY;
1022 nY += pEntry->maSize.Height();
1024 if( pEntry->mnEntryId != TITLE_ID )
1026 if ( ( nOldY <= nMouseY ) && ( nY > nMouseY ) )
1028 if( nEntry != mpImpl->mnHighlightedEntry )
1030 implChangeHighlightEntry( nEntry );
1032 bHighlighted = true;
1036 else
1038 nY += SEPARATOR_HEIGHT;
1041 if ( !bHighlighted )
1042 implChangeHighlightEntry( -1 );
1044 else
1046 implChangeHighlightEntry( -1 );
1050 // --------------------------------------------------------------------
1052 void ToolbarMenu::implChangeHighlightEntry( int nEntry )
1054 if( mpImpl->mnHighlightedEntry != -1 )
1056 implHighlightEntry( mpImpl->mnHighlightedEntry, false );
1059 mpImpl->mnHighlightedEntry = nEntry;
1060 Invalidate();
1062 if( mpImpl->mnHighlightedEntry != -1 )
1064 implHighlightEntry( mpImpl->mnHighlightedEntry, true );
1067 mpImpl->notifyHighlightedEntry();
1070 // --------------------------------------------------------------------
1072 static bool implCheckSubControlCursorMove( Control* pControl, bool bUp, int& nLastColumn )
1074 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
1075 if( pValueSet )
1077 sal_uInt16 nItemPos = pValueSet->GetItemPos( pValueSet->GetSelectItemId() );
1078 if( nItemPos != VALUESET_ITEM_NOTFOUND )
1080 const sal_uInt16 nColCount = pValueSet->GetColCount();
1081 const sal_uInt16 nLine = nItemPos / nColCount;
1083 nLastColumn = nItemPos - (nLine * nColCount);
1085 if( bUp )
1087 return nLine > 0;
1089 else
1091 const sal_uInt16 nLineCount = (pValueSet->GetItemCount() + nColCount - 1) / nColCount;
1092 return (nLine+1) < nLineCount;
1097 return false;
1100 // --------------------------------------------------------------------
1102 ToolbarMenuEntry* ToolbarMenu::implCursorUpDown( bool bUp, bool bHomeEnd )
1104 int n = 0, nLoop = 0;
1105 if( !bHomeEnd )
1107 n = mpImpl->mnHighlightedEntry;
1108 if( n == -1 )
1110 if( bUp )
1111 n = 0;
1112 else
1113 n = mpImpl->maEntryVector.size()-1;
1115 else
1117 // if we have a currently selected entry and
1118 // cursor keys are used than check if this entry
1119 // has a control that can use those cursor keys
1120 ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
1121 if( pData && pData->mpControl && !pData->mbHasText )
1123 if( implCheckSubControlCursorMove( pData->mpControl, bUp, mpImpl->mnLastColumn ) )
1124 return pData;
1127 nLoop = n;
1129 else
1131 // absolute positioning
1132 if( bUp )
1134 n = mpImpl->maEntryVector.size();
1135 nLoop = n-1;
1137 else
1139 n = -1;
1140 nLoop = mpImpl->maEntryVector.size()-1;
1146 if( bUp )
1148 if ( n )
1149 n--;
1150 else
1151 if( mpImpl->mnHighlightedEntry == -1 )
1152 n = mpImpl->maEntryVector.size()-1;
1153 else
1154 break;
1156 else
1158 if( n < ((int)mpImpl->maEntryVector.size()-1) )
1159 n++;
1160 else
1161 if( mpImpl->mnHighlightedEntry == -1 )
1162 n = 0;
1163 else
1164 break;
1167 ToolbarMenuEntry* pData = mpImpl->maEntryVector[n];
1168 if( pData && (pData->mnEntryId != TITLE_ID) )
1170 implChangeHighlightEntry( n );
1171 return pData;
1173 } while ( n != nLoop );
1175 return 0;
1178 // --------------------------------------------------------------------
1180 void ToolbarMenu_Impl::implHighlightControl( sal_uInt16 nCode, Control* pControl )
1182 ValueSet* pValueSet = dynamic_cast< ValueSet* >( pControl );
1183 if( pValueSet )
1185 const sal_uInt16 nItemCount = pValueSet->GetItemCount();
1186 sal_uInt16 nItemPos = VALUESET_ITEM_NOTFOUND;
1187 switch( nCode )
1189 case KEY_UP:
1191 const sal_uInt16 nColCount = pValueSet->GetColCount();
1192 const sal_uInt16 nLastLine = nItemCount / nColCount;
1193 nItemPos = std::min( ((nLastLine-1) * nColCount) + mnLastColumn, nItemCount-1 );
1194 break;
1196 case KEY_DOWN:
1197 nItemPos = std::min( mnLastColumn, nItemCount-1 );
1198 break;
1199 case KEY_END:
1200 nItemPos = nItemCount -1;
1201 break;
1202 case KEY_HOME:
1203 nItemPos = 0;
1204 break;
1206 pValueSet->SelectItem( pValueSet->GetItemId( nItemPos ) );
1207 notifyHighlightedEntry();
1211 // --------------------------------------------------------------------
1213 void ToolbarMenu::KeyInput( const KeyEvent& rKEvent )
1215 Control* pForwardControl = 0;
1216 sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode();
1217 switch ( nCode )
1219 case KEY_UP:
1220 case KEY_DOWN:
1222 int nOldEntry = mpImpl->mnHighlightedEntry;
1223 ToolbarMenuEntry*p = implCursorUpDown( nCode == KEY_UP, false );
1224 if( p && p->mpControl )
1226 if( nOldEntry != mpImpl->mnHighlightedEntry )
1228 mpImpl->implHighlightControl( nCode, p->mpControl );
1230 else
1232 // in case we are in a system floating window, GrabFocus does not work :-/
1233 pForwardControl = p->mpControl;
1237 break;
1238 case KEY_END:
1239 case KEY_HOME:
1241 ToolbarMenuEntry* p = implCursorUpDown( nCode == KEY_END, true );
1242 if( p && p->mpControl )
1244 mpImpl->implHighlightControl( nCode, p->mpControl );
1247 break;
1248 case KEY_F6:
1249 case KEY_ESCAPE:
1251 // Ctrl-F6 acts like ESC here, the menu bar however will then put the focus in the document
1252 if( nCode == KEY_F6 && !rKEvent.GetKeyCode().IsMod1() )
1253 break;
1255 implSelectEntry( -1 );
1257 break;
1259 case KEY_RETURN:
1261 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
1262 if ( pEntry && pEntry->mbEnabled && (pEntry->mnEntryId != TITLE_ID) )
1264 if( pEntry->mpControl )
1266 pForwardControl = pEntry->mpControl;
1268 else
1270 implSelectEntry( mpImpl->mnHighlightedEntry );
1274 break;
1275 default:
1277 ToolbarMenuEntry* pEntry = implGetEntry( mpImpl->mnHighlightedEntry );
1278 if ( pEntry && pEntry->mbEnabled && pEntry->mpControl && !pEntry->mbHasText )
1280 pForwardControl = pEntry->mpControl;
1285 if( pForwardControl )
1286 pForwardControl->KeyInput( rKEvent );
1290 // --------------------------------------------------------------------
1291 static void ImplPaintCheckBackground( Window* i_pWindow, const Rectangle& i_rRect, bool i_bHighlight )
1293 sal_Bool bNativeOk = sal_False;
1294 if( i_pWindow->IsNativeControlSupported( CTRL_TOOLBAR, PART_BUTTON ) )
1296 ImplControlValue aControlValue;
1297 ControlState nState = CTRL_STATE_PRESSED | CTRL_STATE_ENABLED;
1299 aControlValue.setTristateVal( BUTTONVALUE_ON );
1301 bNativeOk = i_pWindow->DrawNativeControl( CTRL_TOOLBAR, PART_BUTTON,
1302 i_rRect, nState, aControlValue,
1303 OUString() );
1306 if( ! bNativeOk )
1308 const StyleSettings& rSettings = i_pWindow->GetSettings().GetStyleSettings();
1309 Color aColor( i_bHighlight ? rSettings.GetMenuHighlightTextColor() : rSettings.GetHighlightColor() );
1310 i_pWindow->DrawSelectionBackground( i_rRect, 0, i_bHighlight, sal_True, sal_False, 2, NULL, &aColor );
1314 void ToolbarMenu::implPaint( ToolbarMenuEntry* pThisOnly, bool bHighlighted )
1316 sal_uInt16 nBorder = 0; long nStartY = 0; // from Menu implementations, needed when we support native menu background & scrollable menu
1318 long nFontHeight = GetTextHeight();
1319 // long nExtra = nFontHeight/4;
1321 long nCheckHeight = 0, nRadioHeight = 0, nMaxCheckWidth = 0;
1322 ImplGetNativeCheckAndRadioSize( this, nCheckHeight, nRadioHeight, nMaxCheckWidth );
1324 DecorationView aDecoView( this );
1325 const StyleSettings& rSettings = GetSettings().GetStyleSettings();
1326 const bool bUseImages = rSettings.GetUseImagesInMenus();
1328 int nOuterSpace = 0; // ImplGetSVData()->maNWFData.mnMenuFormatExtraBorder;
1329 Point aTopLeft( nOuterSpace, nOuterSpace ), aTmpPos;
1331 Size aOutSz( GetOutputSizePixel() );
1332 const int nEntryCount = mpImpl->maEntryVector.size();
1333 int nEntry;
1334 for( nEntry = 0; nEntry < nEntryCount; nEntry++ )
1336 ToolbarMenuEntry* pEntry = mpImpl->maEntryVector[nEntry];
1338 Point aPos( aTopLeft );
1339 aPos.Y() += nBorder;
1340 aPos.Y() += nStartY;
1343 if( (pEntry == 0) && !pThisOnly )
1345 // Separator
1346 aTmpPos.Y() = aPos.Y() + ((SEPARATOR_HEIGHT-2)/2);
1347 aTmpPos.X() = aPos.X() + 2 + nOuterSpace;
1348 SetLineColor( rSettings.GetShadowColor() );
1349 DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
1350 aTmpPos.Y()++;
1351 SetLineColor( rSettings.GetLightColor() );
1352 DrawLine( aTmpPos, Point( aOutSz.Width() - 3 - 2*nOuterSpace, aTmpPos.Y() ) );
1353 SetLineColor();
1355 else if( !pThisOnly || ( pEntry == pThisOnly ) )
1357 const bool bTitle = pEntry->mnEntryId == TITLE_ID;
1359 if ( pThisOnly && bHighlighted )
1360 SetTextColor( rSettings.GetMenuHighlightTextColor() );
1362 if( aPos.Y() >= 0 )
1364 long nTextOffsetY = ((pEntry->maSize.Height()-nFontHeight)/2);
1366 sal_uInt16 nTextStyle = 0;
1367 sal_uInt16 nSymbolStyle = 0;
1368 sal_uInt16 nImageStyle = 0;
1370 if( !pEntry->mbEnabled )
1372 nTextStyle |= TEXT_DRAW_DISABLE;
1373 nSymbolStyle |= SYMBOL_DRAW_DISABLE;
1374 nImageStyle |= IMAGE_DRAW_DISABLE;
1377 Rectangle aOuterCheckRect( Point( aPos.X()+mpImpl->mnCheckPos, aPos.Y() ), Size( pEntry->maSize.Height(), pEntry->maSize.Height() ) );
1378 aOuterCheckRect.Left() += 1;
1379 aOuterCheckRect.Right() -= 1;
1380 aOuterCheckRect.Top() += 1;
1381 aOuterCheckRect.Bottom() -= 1;
1383 if( bTitle )
1385 // fill the background
1386 Rectangle aRect( aTopLeft, Size( aOutSz.Width(), pEntry->maSize.Height() ) );
1387 SetFillColor(rSettings.GetDialogColor());
1388 SetLineColor();
1389 DrawRect(aRect);
1390 SetLineColor( rSettings.GetLightColor() );
1391 DrawLine( aRect.TopLeft(), aRect.TopRight() );
1392 SetLineColor( rSettings.GetShadowColor() );
1393 DrawLine( aRect.BottomLeft(), aRect.BottomRight() );
1396 // CheckMark
1397 if ( pEntry->HasCheck() )
1399 // draw selection transparent marker if checked
1400 // onto that either a checkmark or the item image
1401 // will be painted
1402 // however do not do this if native checks will be painted since
1403 // the selection color too often does not fit the theme's check and/or radio
1405 if( !pEntry->mbHasImage )
1407 if( this->IsNativeControlSupported( CTRL_MENU_POPUP,
1408 (pEntry->mnBits & MIB_RADIOCHECK)
1409 ? PART_MENU_ITEM_CHECK_MARK
1410 : PART_MENU_ITEM_RADIO_MARK ) )
1412 ControlPart nPart = ((pEntry->mnBits & MIB_RADIOCHECK)
1413 ? PART_MENU_ITEM_RADIO_MARK
1414 : PART_MENU_ITEM_CHECK_MARK);
1416 ControlState nState = 0;
1418 if ( pEntry->mbChecked )
1419 nState |= CTRL_STATE_PRESSED;
1421 if ( pEntry->mbEnabled )
1422 nState |= CTRL_STATE_ENABLED;
1424 if ( bHighlighted )
1425 nState |= CTRL_STATE_SELECTED;
1427 long nCtrlHeight = (pEntry->mnBits & MIB_RADIOCHECK) ? nCheckHeight : nRadioHeight;
1428 aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - nCtrlHeight)/2;
1429 aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - nCtrlHeight)/2;
1431 Rectangle aCheckRect( aTmpPos, Size( nCtrlHeight, nCtrlHeight ) );
1432 DrawNativeControl( CTRL_MENU_POPUP, nPart, aCheckRect, nState, ImplControlValue(), OUString() );
1433 aPos.setX( aPos.getX() + nCtrlHeight + gfxExtra );
1435 else if ( pEntry->mbChecked ) // by default do nothing for unchecked items
1437 ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
1439 SymbolType eSymbol;
1440 Size aSymbolSize;
1441 if ( pEntry->mnBits & MIB_RADIOCHECK )
1443 eSymbol = SYMBOL_RADIOCHECKMARK;
1444 aSymbolSize = Size( nFontHeight/2, nFontHeight/2 );
1446 else
1448 eSymbol = SYMBOL_CHECKMARK;
1449 aSymbolSize = Size( (nFontHeight*25)/40, nFontHeight/2 );
1451 aTmpPos.X() = aOuterCheckRect.Left() + (aOuterCheckRect.GetWidth() - aSymbolSize.Width())/2;
1452 aTmpPos.Y() = aOuterCheckRect.Top() + (aOuterCheckRect.GetHeight() - aSymbolSize.Height())/2;
1453 Rectangle aRect( aTmpPos, aSymbolSize );
1454 aDecoView.DrawSymbol( aRect, eSymbol, GetTextColor(), nSymbolStyle );
1455 aPos.setX( aPos.getX() + aSymbolSize.getWidth( ) + gfxExtra );
1460 // Image:
1461 if( pEntry->mbHasImage && bUseImages )
1463 if( pEntry->mbChecked )
1464 ImplPaintCheckBackground( this, aOuterCheckRect, pThisOnly && bHighlighted );
1465 aTmpPos = aOuterCheckRect.TopLeft();
1466 aTmpPos.X() += (aOuterCheckRect.GetWidth()-pEntry->maImage.GetSizePixel().Width())/2;
1467 aTmpPos.Y() += (aOuterCheckRect.GetHeight()-pEntry->maImage.GetSizePixel().Height())/2;
1468 DrawImage( aTmpPos, pEntry->maImage, nImageStyle );
1471 // Text:
1472 if( pEntry->mbHasText )
1474 aTmpPos.X() = aPos.X() + (bTitle ? 4 : mpImpl->mnTextPos);
1475 aTmpPos.Y() = aPos.Y();
1476 aTmpPos.Y() += nTextOffsetY;
1477 sal_uInt16 nStyle = nTextStyle|TEXT_DRAW_MNEMONIC;
1479 DrawCtrlText( aTmpPos, pEntry->maText, 0, pEntry->maText.Len(), nStyle, NULL, NULL ); // pVector, pDisplayText );
1482 if ( pThisOnly && bHighlighted )
1484 // This restores the normal menu or menu bar text
1485 // color for when it is no longer highlighted.
1486 SetTextColor( rSettings.GetMenuTextColor() );
1491 aTopLeft.Y() += pEntry ? pEntry->maSize.Height() : SEPARATOR_HEIGHT;
1495 // --------------------------------------------------------------------
1497 void ToolbarMenu::Paint( const Rectangle& )
1499 SetFillColor( GetSettings().GetStyleSettings().GetMenuColor() );
1501 implPaint();
1503 if( mpImpl->mnHighlightedEntry != -1 )
1504 implHighlightEntry( mpImpl->mnHighlightedEntry, true );
1507 // --------------------------------------------------------------------
1509 void ToolbarMenu::RequestHelp( const HelpEvent& rHEvt )
1511 DockingWindow::RequestHelp( rHEvt );
1514 // --------------------------------------------------------------------
1516 void ToolbarMenu::StateChanged( StateChangedType nType )
1518 DockingWindow::StateChanged( nType );
1520 if ( ( nType == STATE_CHANGE_CONTROLFOREGROUND ) || ( nType == STATE_CHANGE_CONTROLBACKGROUND ) )
1522 initWindow();
1523 Invalidate();
1527 // --------------------------------------------------------------------
1529 void ToolbarMenu::DataChanged( const DataChangedEvent& rDCEvt )
1531 DockingWindow::DataChanged( rDCEvt );
1533 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1534 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1535 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1536 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1538 initWindow();
1539 Invalidate();
1543 // --------------------------------------------------------------------
1545 void ToolbarMenu::Command( const CommandEvent& rCEvt )
1547 if ( rCEvt.GetCommand() == COMMAND_WHEEL )
1549 const CommandWheelData* pData = rCEvt.GetWheelData();
1550 if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
1552 implCursorUpDown( pData->GetDelta() > 0L, false );
1557 // --------------------------------------------------------------------
1559 Reference< ::com::sun::star::accessibility::XAccessible > ToolbarMenu::CreateAccessible()
1561 mpImpl->setAccessible( new ToolbarMenuAcc( *mpImpl ) );
1562 return Reference< XAccessible >( mpImpl->mxAccessible.get() );
1565 // --------------------------------------------------------------------
1567 // todo: move to new base class that will replace SfxPopupWindo
1568 void ToolbarMenu::AddStatusListener( const OUString& rCommandURL )
1570 initStatusListener();
1571 mpImpl->mxStatusListener->addStatusListener( rCommandURL );
1574 // --------------------------------------------------------------------
1576 // XStatusListener (subclasses must override this one to get the status updates
1577 void SAL_CALL ToolbarMenu::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& /*Event*/ ) throw ( ::com::sun::star::uno::RuntimeException )
1581 // --------------------------------------------------------------------
1583 class ToolbarMenuStatusListener : public svt::FrameStatusListener
1585 public:
1586 ToolbarMenuStatusListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
1587 ToolbarMenu& rToolbarMenu );
1589 virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException);
1590 virtual void SAL_CALL statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException );
1592 ToolbarMenu* mpMenu;
1595 // --------------------------------------------------------------------
1597 ToolbarMenuStatusListener::ToolbarMenuStatusListener(
1598 const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame,
1599 ToolbarMenu& rToolbarMenu )
1600 : svt::FrameStatusListener( ::comphelper::getProcessComponentContext(), xFrame )
1601 , mpMenu( &rToolbarMenu )
1605 // --------------------------------------------------------------------
1607 void SAL_CALL ToolbarMenuStatusListener::dispose() throw (::com::sun::star::uno::RuntimeException)
1609 mpMenu = 0;
1610 svt::FrameStatusListener::dispose();
1613 // --------------------------------------------------------------------
1615 void SAL_CALL ToolbarMenuStatusListener::statusChanged( const ::com::sun::star::frame::FeatureStateEvent& Event ) throw ( ::com::sun::star::uno::RuntimeException )
1617 if( mpMenu )
1618 mpMenu->statusChanged( Event );
1621 // --------------------------------------------------------------------
1623 void ToolbarMenu::initStatusListener()
1625 if( !mpImpl->mxStatusListener.is() )
1626 mpImpl->mxStatusListener.set( new ToolbarMenuStatusListener( mpImpl->mxFrame, *this ) );
1629 // --------------------------------------------------------------------
1631 bool ToolbarMenu::IsInPopupMode()
1633 return GetDockingManager()->IsInPopupMode(this);
1636 // --------------------------------------------------------------------
1638 void ToolbarMenu::EndPopupMode()
1640 GetDockingManager()->EndPopupMode(this);
1643 // --------------------------------------------------------------------
1645 const Size& ToolbarMenu::getMenuSize() const
1647 return mpImpl->maSize;
1650 // --------------------------------------------------------------------
1652 void ToolbarMenu::SetSelectHdl( const Link& rLink )
1654 mpImpl->maSelectHdl = rLink;
1657 // --------------------------------------------------------------------
1662 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */